At one point I was learning a little domain-driven design. The book I was reading1 Patterns, Principles, and Practices of Domain-Driven Design; Millett & Tune; Wrox; 2015. pointed out a mistake that more experienced software developers make: There is such a thing as too much code reuse (or equivalently, not enough copy–paste). Code can be too dry.
The problem with reuse is that it can couple things that are actually different.
As an example, in a filing system for a legal firm, there will be a temptation to make a Contract class. And that’s the only representation of a contract, and it will support all the things anyone in the organisation wants to do with a contract. But really, a lawyer and an archivist think of a contract in very different ways. The lawyer sees the contract as a binding legal agreement with structured and unstructured data. To the archivist it’s just an important paper. They will have very different ideas of what operations it should support.
Trying to represent both their desires in a single model is going to couple their respective domains and make the contract object very complicated. It will be hard to evolve the separate domains without having them interfere with each other.
It makes sense in such situations to model the same physical artifact in
completely different way in different domains. Have two different
objects, one used by the lawyer side of the software, and a different one used
by the archivist side of the software. It can still be stored in only one
location, but represented differently in different parts of the
application.2 If the different domains are maintained by different people,
storing both concepts in one location turns the storage schema into a barrier
(in the synchronisation point sense) between the maintainers, adding drag to the
process. It might, in other words, make sense also to store the different
representations of something in different ways. This – gasp – introduces
duplication of data as well as representation. It risks diverging contents of
the same object. That’s usually not the end of the world. Or you have to be
In other words, when you find repetition in your code, you need to ask yourself whether it’s incidental repetition (things just look similar; they aren’t similar conceptually) or concept repetition (two things actually refer to the same thing – even if it doesn’t look similar in the code!)
You might be surprised at how often reduced coupling should take priority over code reuse.