“Don’t Repeat Yourself” is one of the first principles we learn, which is exactly why it’s one of the most misapplied. We see two similar lines and rush to create a shared function. Sometimes that’s a mistake.
The hidden cost of abstraction
When you merge two pieces of code that look alike but answer different needs, you create coupling. The day one of the two cases changes, you add a parameter, then an if, then another flag… until the “abstraction” is harder to read than the original duplication.
The practical rule
Sandi Metz nails it: “prefer duplication over the wrong abstraction”. And the famous rule of three:
Don’t abstract on the first repetition. Nor the second. By the third, you have enough information to see the real pattern.
The right question
It’s not “does this code look similar?” but “do these two places change for the same reason?”.
- If they’ll always change together → abstract.
- If they can evolve separately → leave them duplicated, even if they look identical today.
That’s the difference between incidental duplication (coincidence) and real duplication (same business rule).
Takeaway
DRY is a good heuristic, not a law. A bit of deliberate WET (“Write Everything Twice”) often produces code that’s easier to change than a forced abstraction. Optimize for change, not for coincidence.