Design Patterns

Anti-Patterns & Pattern Misuse

An anti-pattern is a recognizable, recurring "solution" that looks reasonable but reliably makes a codebase worse. Many are what happens when a legitimate design pattern is applied without the problem it was meant to solve.
  • Golden Hammer: forcing every problem to fit one favorite pattern or technology regardless of fit — "when your only tool is Observer, every problem looks like a notification"
  • God Object / Blob: a single class that knows or does too much, violating Solid Principles's single-responsibility principle at the extreme
  • Singleton overuse: using Singleton as a substitute for proper dependency management, producing hidden global state and untestable code (Creational Patterns)
  • Premature pattern application: introducing a pattern's indirection (an interface with exactly one implementation, a Factory for a type that's never actually varied) before there's a real need for the flexibility it buys
  • The fix for all of these is the same discipline: introduce a pattern in response to an observed, real problem — duplicated conditional logic, an untested global, a class that keeps growing — not preemptively
Anti-pattern → usually a misapplied pattern
Anti-patternWhat it looks likeRoot cause
God Objectone class with dozens of methods and responsibilitiesmissing single-responsibility discipline
Singleton abuseglobal mutable state accessed via getInstance() everywherereaching for Singleton instead of dependency injection
Interface pollutionan interface with exactly one implementation, never variedStrategy/Factory applied with no actual variability to abstract over
Golden Hammerthe same pattern reused for unrelated problemsfamiliarity with one pattern outweighing fit to the problem
A Factory that solves no problem
// Anti-pattern: a Factory with exactly one product, forever
interface ShapeFactory { Shape create(); }
class CircleFactory implements ShapeFactory { public Shape create() { return new Circle(); } }

// If Circle is genuinely the only shape that will ever exist, this is pure ceremony:
Shape s = new CircleFactory().create();

// vs. just:
Shape s2 = new Circle();   // equally correct, and honest about there being no variability yet
Introduce the Factory when a second concrete Shape actually shows up — not before
Sources
  • Head First Design Patterns (2nd ed.)Ch. 1, 13 — Introduction; Patterns in the Real World
  • Refactoring: Improving the Design of Existing Code (2nd ed.)Ch. 3 — Bad Smells in Code