Design Patterns: Overcomplicating What We Already Know?
Share this article
The Pattern Recognition Paradox
Every developer knows the feeling: You encounter a new "design pattern," panic that you're missing crucial knowledge, then realize it describes something you've implemented countless times. As one frustrated programmer notes, the Command pattern—which "encapsulates all information needed to perform an action"—is fundamentally just a function:
const command = () => object.method(arg1, arg2);
This revelation sparks a deeper critique: Why do we formalize basic programming concepts into patterns that often complicate rather than clarify?
When Patterns Become Noise
The core issue lies in categorization. Patterns like Iterator represent concrete interfaces (IEnumerator), while others like Mediator are vague architectural suggestions. This inconsistency forces mental translation:
"When you say 'facade,' my mind screeches to a halt... I need to switch gears and translate it from human language to programming language."
This cognitive friction contradicts good design principles—excellent architecture should be invisible, not require pattern-to-code dictionary lookups. The problem intensifies with "glue patterns" like Strategy ("use an interface") or Command ("pass a closure"), which describe fundamental language features rather than novel solutions.
The Communication Breakdown
Proponents argue pattern names enable concise communication, but real-world usage reveals mismatches:
- Say "Factory," write
function newFoo - Say "Prototype," write
function clone - JavaScript's
Class.prototype≠ Prototype pattern
Patterns also fail as universal vocabulary due to language constraints. Singletons are redundant in ecosystems comfortable with globals, while Rust's lifetime patterns have no equivalent in OOP languages. When Wikipedia's Abstract Factory definition requires legal-text-level parsing to describe what amounts to type-erased constructors, something's amiss:
"Now that I can see the signature, I understand that it's incredibly obvious. And that makes it useless."
Principles Over Patterns
The solution lies in focusing on underlying goals:
1. Communicate intent: Say "decoupling X from Y" instead of "using Mediator"
2. Embrace language idioms: Use closures over Factory classes where appropriate
3. Teach fundamentals: SOLID principles create better intuition than pattern catalogs
As the author observes, patterns emerge naturally through iterative problem-solving. When making a library server-compatible, passing document as a parameter inadvertently creates an abstract factory—no terminology required.
The Way Forward
While patterns provided value when languages lacked first-class functions or interfaces, modern ecosystems make them less essential. As one developer pleads:
"Walk me through a use case or two and then never mention the pattern by name again."
Pattern literacy has merits, but obsessing over taxonomy distracts from writing clear, maintainable code. The most elegant solutions often emerge when we focus on the problem—not the pattern book.
Source: If I Hear ‘Design Pattern’ One More Time I’ll Go Mad