A codebase uses many design patterns and is harder to understand than an equivalent one that uses few. What went wrong?
Show the full answer Hide the answer
What went wrong
Patterns applied as goals rather than as solutions to problems the code had.
A design pattern is a named solution to a recurring problem with a stated context and stated consequences. Applied where the problem does not exist, it delivers only the consequences — indirection, additional types, and a longer path from a request to the code that does the work.
The characteristic symptom is that following a single operation means opening nine files, most of which delegate.
The specific misuses
1. Factories where construction is trivial. A factory exists to decouple the choice of implementation from its use. With one implementation and no configuration, it is a function call with a ceremony.
2. Strategy for a decision that never varies. An interface with one implementation is speculative abstraction: a guess about future variation that adds cost now and is usually wrong about what varies.
3. Observer where a direct call would do, making control flow untraceable in exchange for a decoupling nobody needed.
4. Repository over a data access layer that is already an abstraction, producing a wrapper whose interface mirrors the thing it wraps.
5. Layers of decorators obscuring what actually executes.
The correct application
Introduce a pattern when the problem it solves has appeared — typically at the second or third case, when the axis of variation is known rather than imagined. Two implementations tell you where the seam belongs; one implementation and an imagination do not.
The value patterns genuinely deliver
Vocabulary. Saying "this is an adapter" or "we use an outbox here" conveys a structure and its consequences in three words. That communication value is real and is the main reason to know them.
The corollary: naming a structure after a pattern it does not implement is worse than not naming it, because it conveys consequences the code does not have.
The test
What change does this indirection make cheaper, and how likely is that change? If the answer is a hypothetical future requirement, the cost is certain and the benefit is not — which is the same failure as speculative abstraction generally, wearing a more respectable name.