When does introducing a design pattern make a codebase worse?
Show the full answer Hide the answer
What is being tested
Whether you treat patterns as vocabulary for recognising structures rather than as goals to achieve.
The three ways it goes wrong
1. Speculative generality. A pattern introduced before the variation it accommodates has appeared. A strategy interface with one implementation, a factory producing one type, an abstract base class with one subclass. Each is indirection paid for now against an option that may never be exercised — and every reader afterwards must navigate it to understand what the code does.
The classic form is a factory producing a strategy configured by a builder, for a system with one implementation of everything.
2. Compensating for language features. Several classic patterns exist to work around limitations of 1990s object-oriented languages. In a language with first-class functions, "strategy" is passing a function; implementing the full pattern structure adds ceremony and subtracts clarity. Applying the catalogue mechanically across languages is cargo-culting.
3. Patterns as names instead of descriptions. OrderStrategyFactoryImpl tells the reader about the
implementation mechanism and nothing about what it does. Names should describe purpose.
The healthy relationship
Recognise the pattern when the problem appears; do not seek the problem to justify the pattern.
Write the direct code. When the second and third variations arrive, the refactor to a named structure is obvious, mechanical and safe — and by then you know what varies, which you did not before.
Patterns are most useful read backwards: not "which pattern shall I apply" but "the shape I have arrived at is called X, which tells me what usually goes wrong with it next." That is genuine value, because the catalogue carries accumulated knowledge about consequences.
The real value: vocabulary
"Use a strategy here" communicates a structure in three words to anyone who shares the vocabulary. That compression operates in design discussion, code review and documentation, and it is the main benefit.
For an architect the architectural catalogue matters far more than the object-level one — circuit breaker, bulkhead, saga, outbox, strangler fig, sidecar, anti-corruption layer. Those have consequences measured in outages and migration programmes rather than in file counts.
What a strong answer adds
That the same reasoning applies at every altitude. Adopting a service mesh, an event streaming platform or CQRS "because they are good patterns" is the identical error one level up, with a much larger bill.