Assume we have a software module A that implements a function F. Another module B implements the same function as F'.
There are a number of ways to get rid of the duplicate code:
- Let A use F' from B.
- Let B use F from A.
- Put F into its own module C and let both A and B use it.
All of these options generate additional dependencies between modules. They apply the DRY principle at the cost of increasing coupling.
As far as I can see, coupling is always increased or at leased moved to a higher level when applying DRY. There seems to be a conflict between two of the most basic principles of software design.
(Actually I don't find it surprising that there are conflicts like that. This is probably what makes good software design so difficult. I do find it surprising that these conflicts are normally not addressed in introductory texts.)
Edit (for clarification): I assume that the equality of F and F' is not just a coincidence. If F will have to be modified, F' will likely have to be modified in the same way.
you should copy/paste F into B just for the sake of maintaining the conceptual autonomy of A and B but I haven't ran into a scenario where I would do that.Both are valid approaches depending on the context. For example, just becausePersonandCountryboth have astring Nameproperty doesn't mean that they share the same reused property. If a country's name becomes anint, that doesn't mean that people's names also get turned intoint. You should only abstract reused logic and you should avoid abstracting currently similar logic. – Flater Jul 16 '18 at 09:26Nameif it was complex enough and let both classes use it. If it were just a "property" with little behavior I might copy/paste it. Though to be fair I am currently maintaining a codebase where the author copy/pasted an entire giant class including duplicated mathematical function implementations that have no reason to differ between implementations, so I've been living the "copy/paste cleanup" life for a while now. – jrh Jul 16 '18 at 16:41