Contents
Two developers argue in code review. One says: "we need a Decorator here." The other: "it's just an if." A month later — three wrapper layers nobody can trace, and a bug in call order. Sound familiar?
Design Patterns (GoF, 1994) is not a checklist to insert a pattern into every module. It is a vocabulary for recurring design problems: name a solution, discuss it in review, avoid reinventing alone. Below — how the book reads in 2026, where it becomes cargo-cult, and how AI worsens "pattern soup." This digest does not replace the book.
The book's thesis
A design pattern is a named, proven solution to a recurring problem in object-oriented systems. GoF gives language: Strategy, Observer, Factory Method — not buzzwords, but references to structure, trade-offs, and consequences.
Examples in C++ and Smalltalk aged syntactically; problems remain: isolate change, connect objects without spaghetti, create object families. The classic reader mistake is memorizing 23 patterns and hunting slots for each. Better — recognize the situation and recall the move, like a chess player recognizes a line.
Key ideas
Pattern as team vocabulary, not KPI
What the author says. A pattern captures problem, context, solution, consequences. Saying "Facade" or "Adapter" saves ten minutes on the whiteboard. Goal is shared language, not a "we use patterns" badge.
Enterprise. Bank API changes every quarter. Instead of "wrapper over wrapper," review says: "Adapter with a narrow domain interface." New hire opens the catalog, sees structure, does not rewrite from scratch.
AI today. Models generate AbstractFactory and Visitor where a function suffices. Diff looks "architectural," review misses it. Ask: "describe the problem without a pattern; then suggest one GoF name if truly needed."
Where it fails. Small CRUD — plain names beat pattern jargon.
Do today. On next review ask: "what problem are we solving?" before naming a pattern.
My take. GoF saves cross-team talk and legacy onboarding. When the pattern becomes the goal — the book hurts.
One takeaway: problem first, catalog name second.
Program to an interface, not an implementation
What the author says. Depending on abstractions lowers coupling: swap implementations, test with fakes, evolve subsystems separately.
Enterprise. Notification service depends on Notifier, not a concrete SMS gateway. New channel — new implementation, domain unchanged.
AI today. "Interface per class" zoo — one-method interfaces everywhere. Human filter: two implementations or real swap ahead?
Where it fails. YAGNI before second implementation. In TS, unions often play the interface role — same idea, different shape.
Do today. Find one concrete-class dependency in your task — need swap in tests or next release?
My take. The most alive GoF line in 2026. The rest are special cases of not nailing code to one implementation.
One takeaway: interface where a second implementation is coming.
Favor composition over inheritance
What the author says. Inheritance binds subclasses tightly; composition (contain and delegate) flexes. Decorator, Strategy, Bridge — about this.
Enterprise. Extending a report class per format (PDF, Excel, API) explodes hierarchy. Strategy for renderer + composed report data — add format without touching base.
AI today. Deep inheritance trees "look OOP." Catch when extends should become field + delegation.
Where it fails. Some frameworks mandate inheritance; domain code usually prefers composition.
Do today. One extends in your task — replaceable with composition?
My take. Links to Fowler's Refactoring — Replace Inheritance with Delegation.
One takeaway: inheritance for stable is-a; behavior via composition.
Creational: flexible creation, not Singleton by default
Factory Method, Abstract Factory, Builder, Prototype — who creates how when new is not enough. Singleton — creational with caveats.
Enterprise. Builder for documents with many optional fields beats 14-arg constructors. Factory picks PaymentGateway from config. Singleton DB "the one connection" — test and scale pain.
AI today. Singleton "for cache" = global state. Review: one instance per process or lazy habit?
Do today. See Singleton — ask how tests avoid global state.
My take. Builder and Factory stay daily; new-code Singleton is a red flag unless OS-level resource.
One takeaway: creational patterns are about creation variants, not pretty factories.
Behavioral: Strategy and Observer for change
Strategy — interchangeable algorithms. Observer — notify without tight coupling. Command, State, Iterator — other answers to how objects collaborate.
Enterprise. Tax rules by country — Strategy, not 200-line switch. UI on model change — Observer (or events, reactive streams).
AI today. Generates switch; Strategy refactor is a good post-test agent task. Microservices often use brokers — subscribers still don't know each other.
Do today. One big type/status switch — Strategy candidate?
My take. Strategy and Observer survive in legacy most often.
One takeaway: behavioral patterns buy behavior change flexibility.
Structural: Adapter and Facade at boundaries
Adapter — foreign interface to yours. Facade — simple entry to complex subsystem. Decorator — add duties without subclasses. Proxy — control access.
Enterprise. SOAP outside, REST inside — Adapter for domain. Facade over five billing services — one "issue invoice" for frontend. Good Facade narrows surface, not pass-through every method.
AI today. Useless Facades that only delegate everything.
Do today. At external API boundary sketch: our interface vs theirs — need Adapter?
My take. Facade and Adapter are daily integration horses.
One takeaway: structural patterns live at boundaries and layers.
In practice
On review: problem before pattern name? Simpler solution without new layer? Hooks/middleware/plugins are often the same ideas — find dependency shape, not class named Observer.
| Idea | Junior | Middle | Senior |
|---|---|---|---|
| Pattern as vocabulary | ★★★★ | ★★★★★ | ★★★★★ |
| Interface vs implementation | ★★★★★ | ★★★★★ | ★★★★ |
| Composition vs inheritance | ★★★★ | ★★★★★ | ★★★★★ |
| Creational | ★★★★ | ★★★★★ | ★★★★ |
| Behavioral | ★★★★ | ★★★★★ | ★★★★★ |
| Structural | ★★★★ | ★★★★★ | ★★★★★ |
Limits and critique
GoF examples age, problems don't. Pattern-omania worse than no catalog. Much is built into frameworks. FP questions some OO forms — "isolate change" remains.
Compare. GoF — named shapes. Clean Code — local readability. Refactoring — change form safely. DDD — which model; GoF — how objects connect.
Read GoF as reference and language, not 23 Jira checkboxes.
Who should read
Worth it for non-trivial modules, integrations, changing rules, legacy with Factory/Observer. Selective if framework gives everything — know 5–6 patterns from articles. Caution if team counts patterns as architecture metric.
What to try today
- Name one problem in current module — one GoF pattern or simple refactor?
- One type switch — Strategy only if variants grow or tests need swap.
- On AI diff — no new class hierarchies without "which problem."
- Read one original chapter (Strategy or Adapter) against your code.

