1

I've about seven modules arranged like so:

  • Service
  • Processing
  • Common
  • Account
  • Email
  • Scheduling

I try to make it my policy to restrict code to the module that actually uses it. Code that is shared by multiple projects (3+) is sent to common. However, there are a few classes that are only used by two projects. In my most recent example, both Account and Processing need some Image Processing done.

Is it a code smell two have the same classes found in two modules? Should I move duplicate code into common as soon as it it's used more than once?

  • 1
    Why 3? Is that a magic number that some authority quoted? Isn't it obvious that you save more and more effort by factoring out common utility code the longer it gets, even if it's only used in two places? – Kilian Foth Feb 12 '14 at 14:29
  • I believe that I use the magic three from a book by Martin Fowler. It went something like, "Don't refactor immediately. If you write it twice, wince at the duplication. If you write it a third time, refactor." – IAE Feb 12 '14 at 14:33
  • Okay, then that probably is meant to apply to individual lines of code that you write twice, but probably not to entire methods or classes. – Kilian Foth Feb 12 '14 at 14:35
  • The only other source I've relied on for this is a german article by the creators of Otto.de, which describe a similar model of development. They explicitly state that they do not share their code unless absolutely necessary which minimizes dependencies, but creates code duplication. I didn't think it was that bad, but writing this project has driven me to have second thoughts. – IAE Feb 12 '14 at 14:36
  • Is there a reason why Image Process doesn't deserve its own module? – JeffO Feb 12 '14 at 15:40
4

I really like the DRY principle from pragmatic programmers to describe this type of situation:

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

What its the advantage of maintain two different representations of the same knowledge in a system?, IMMO this only can cause problems.

2

Anything that is used more than once should be put into a common location, if the usage is between different projects. Code duplication is the root of all evil and you can't be sure that a bug fixed in one location will get fixed in all the duplicate locations.

In terms of maintenance future developers could find it confusing to see two classes that are exactly the same in multiple locations.

  • Thank you for the answer! However, if I move something to common, then all other projects reference it, a class that was meant for two classes suddenly is accessible for all. This also means that dependencies are moved from a contained module into common. Is that wise? Is that still slaying the root of all evil, code duplication, without sacrificing it for another evil? – IAE Feb 12 '14 at 14:34
  • Imagine in the future you need to use this common class again as a dependency in a new feature, are you going to duplicate the class again? I think it would be better to host it in the common project. After all, if it is being referenced by multiple classes then it is a common class. – stuartmclark Feb 12 '14 at 14:39
  • 4
    'common' dependencies are an antipattern. Create a dependency that suits the class, even if that dependency is very small. You don't want a large bucket of "this is where we throw things we don't know where else to put." – Michael K Feb 12 '14 at 14:41
  • Are you disagreeing with the practice? How would you solve it if not with either of our suggestions? You mean to recreate the classes to suit the needs of the module or containing class that need it? – IAE Feb 12 '14 at 14:44
  • Perhaps a Utilities project would suffice for classes of this nature which carry out an action required by multiple projects. – stuartmclark Feb 12 '14 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.