Skip to content

Design Patterns Overview

Design patterns are reusable solutions to commonly occurring problems in software design. They’re not code you copy — they’re templates for solving problems in a particular context.

First catalogued by the “Gang of Four” (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) in their 1994 book Design Patterns: Elements of Reusable Object-Oriented Software.

Deal with object creation — how objects are instantiated.

PatternProblem Solved
SingletonEnsure only one instance of a class exists
Factory MethodLet subclasses decide which class to instantiate
Abstract FactoryCreate families of related objects
BuilderConstruct complex objects step by step
PrototypeClone existing objects

Deal with object composition — how objects are assembled from parts.

PatternProblem Solved
AdapterMake incompatible interfaces work together
DecoratorAdd behaviour to objects without subclassing
FacadeSimplify a complex subsystem with a unified interface
ProxyControl access to an object
CompositeTreat individual objects and groups uniformly
BridgeDecouple abstraction from implementation

Deal with communication between objects — how they interact and distribute responsibility.

PatternProblem Solved
StrategyDefine a family of algorithms and make them interchangeable
ObserverNotify dependents when an object changes state
CommandEncapsulate a request as an object
Chain of ResponsibilityPass a request along a chain of handlers
Template MethodDefine a skeleton algorithm, defer steps to subclasses
RepositoryAbstract data access from business logic
IteratorTraverse a collection without exposing its structure

Patterns solve recurring problems. Apply them when:

  • You recognise the problem they address
  • The solution without a pattern would be complex or brittle
  • Team members will understand the pattern

Don’t apply patterns speculatively — “I might need this later” leads to over-engineering. YAGNI (You Aren’t Gonna Need It) applies.

Many patterns are built into modern languages and frameworks:

  • Observer → React’s useEffect, event emitters, RxJS
  • Strategy → function arguments, dependency injection
  • Decorator → Python decorators, TypeScript decorators, middleware
  • Repository → Entity Framework, Prisma, SQLAlchemy
  • Factory → dependency injection containers

Recognising patterns in frameworks helps you use them more effectively.

Design patterns often implement SOLID principles:

PrincipleDescription
Single ResponsibilityA class should have one reason to change
Open/ClosedOpen for extension, closed for modification
Liskov SubstitutionSubtypes must be substitutable for base types
Interface SegregationClients shouldn’t be forced to depend on unused interfaces
Dependency InversionDepend on abstractions, not concretions