Skip to content

Design Patterns

What design patterns are

A design pattern is a named, reusable solution to a recurring problem in object-oriented design. The term was formalized in 1994 by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in Design Patterns: Elements of Reusable Object-Oriented Software. The book cataloged 23 patterns drawn from production codebases and organized them by intent: creational, structural, and behavioral.

Patterns are not code libraries. They describe relationships between classes and objects. The value is a shared vocabulary: saying “use an Observer here” communicates structure, relationships, and tradeoffs in a way that a paragraph of prose cannot.

The Gang of Four book

FieldDetail
TitleDesign Patterns: Elements of Reusable Object-Oriented Software
AuthorsErich Gamma, Richard Helm, Ralph Johnson, John Vlissides
Year1994
PublisherAddison-Wesley
Patterns23

The book’s nickname “the Gang of Four book” refers to its four authors. Each pattern entry follows a fixed template: intent, motivation, applicability, structure (as a UML diagram), participants, collaboration, consequences, implementation notes, sample code in C++ and Smalltalk, known uses, and related patterns.

The three categories

graph LR
DP[GoF Design Patterns]
DP --> C["Creational (5)\nAbstract Factory · Builder\nFactory Method · Prototype · Singleton"]
DP --> S["Structural (7)\nAdapter · Bridge · Composite\nDecorator · Facade · Flyweight · Proxy"]
DP --> B["Behavioral (11)\nChain of Responsibility · Command · Interpreter\nIterator · Mediator · Memento · Observer\nState · Strategy · Template Method · Visitor"]

Creational patterns

Creational patterns separate object construction from use, hiding the concrete classes that get instantiated.

PatternIntent
Abstract FactoryProduce families of related objects without specifying concrete classes
BuilderBuild complex objects step by step, separating construction from representation
Factory MethodDelegate instantiation to subclasses
PrototypeClone an existing object rather than constructing a new one
SingletonEnsure one instance and provide a global access point

Structural patterns

Structural patterns deal with how classes and objects are composed to form larger structures.

PatternIntent
AdapterMake incompatible interfaces work together
BridgeDecouple an abstraction from its implementation
CompositeCompose objects into trees for uniform treatment
DecoratorAdd behavior by wrapping, not subclassing
FacadeProvide a simplified interface to a complex subsystem
FlyweightShare fine-grained objects to reduce memory
ProxyControl access to another object

Behavioral patterns

Behavioral patterns focus on communication and responsibility between objects.

PatternIntent
Chain of ResponsibilityPass a request along a chain of handlers
CommandEncapsulate a request as an object
InterpreterDefine a grammar and an interpreter for a language
IteratorSequential element access without exposing internals
MediatorCentralize communication between objects
MementoCapture and restore an object’s state
ObserverNotify dependents automatically when state changes
StateAlter behavior when internal state changes
StrategyDefine a family of algorithms, encapsulate each, make them interchangeable
Template MethodDefine the skeleton of an algorithm, leave steps to subclasses
VisitorAdd new operations to a class hierarchy without modifying it

Patterns you will encounter most

A handful account for the large majority of real-world encounters:

  • Observer: React state, DOM events, RxJS, EventEmitter.
  • Strategy: Payment providers, auth backends, serialization formats.
  • Factory Method: ORM base classes, plugin systems, test doubles.
  • Builder: Query builders, HTTP client config, gRPC message construction.
  • Facade: SDK wrappers, service clients, third-party API adapters.
  • Command: Undo/redo, task queues, CLI argument parsing.
  • Decorator: Express middleware, Django middleware, logging wrappers.

A note on overuse

GoF patterns solve specific problems. Applied where those problems do not exist, they add indirection without value. Several patterns also compensate for missing language features. Visitor compensates for languages without multiple dispatch. Singleton compensates for languages without module-level singletons. In Python, Go, and modern TypeScript, idiomatic solutions exist that do not require the full ceremony of the pattern.

Read each pattern for the problem it solves.

Subtopics

Creational

  • Abstract Factory, families of related objects without specifying concrete classes
  • Builder, step-by-step object construction with a fluent interface
  • Factory, centralized object creation with Factory Method and Abstract Factory
  • Prototype, clone existing objects rather than constructing new ones
  • Singleton, one instance, global access

Structural

  • Adapter, incompatible interfaces made compatible
  • Bridge, abstraction decoupled from implementation so both can vary
  • Composite, part-whole trees where leaves and branches are treated uniformly
  • Decorator, behavior added by wrapping without subclassing
  • Facade, a simplified surface over a complex subsystem
  • Flyweight, shared intrinsic state to reduce memory use
  • Proxy, controlled access through a surrogate

Behavioral

  • Chain of Responsibility, requests passed along a handler chain until one resolves them
  • Command, requests as first-class objects with undo and queuing
  • Interpreter, a grammar and evaluator for a small language
  • Iterator, sequential element access without exposing internals
  • Mediator, centralized communication between peer objects
  • Memento, snapshot and restore an object’s internal state
  • Observer, automatic notification of dependents on state change
  • State, behavior that changes as internal state changes
  • Strategy, swappable algorithm families
  • Template Method, algorithm skeleton in a base class with steps deferred to subclasses
  • Visitor, new operations on a class hierarchy without modifying it

References