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?

8
  • 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? Feb 12, 2014 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, 2014 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. Feb 12, 2014 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, 2014 at 14:36
  • Is there a reason why Image Process doesn't deserve its own module?
    – JeffO
    Feb 12, 2014 at 15:40

2 Answers 2

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.

5
  • 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, 2014 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. Feb 12, 2014 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, 2014 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, 2014 at 14:44
  • Perhaps a Utilities project would suffice for classes of this nature which carry out an action required by multiple projects. Feb 12, 2014 at 14:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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