Low Level Design

Design Patterns — The Complete Guide

A practical overview of the 23 Gang of Four design patterns — what they are, how they're grouped, and when to reach for each one.

August 26, 2026·8 min read

What are Design Patterns?#

Design patterns are proven, reusable solutions to commonly occurring problems in software design. They are not finished code — they are templates or blueprints that you adapt to your specific situation.

In Low-Level Design (LLD), design patterns provide guidelines for structuring class hierarchies, defining object interactions, and organising code in a way that is:

  • Reusable — the same pattern solves similar problems across different contexts
  • Maintainable — well-known structure makes code easier to read and modify
  • Extensible — patterns align with SOLID principles, especially Open/Closed

Origin — The Gang of Four#

Design patterns were popularised by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in their 1994 book Design Patterns: Elements of Reusable Object-Oriented Software — commonly called the GoF (Gang of Four) book.

The book catalogued 23 patterns grouped into three categories.


The Three Categories#


Creational Patterns — How objects are created#

These patterns abstract the instantiation process, making a system independent of how its objects are created, composed, and represented.

PatternOne-liner
SingletonEnsures a class has exactly one instance
Factory MethodLets subclasses decide which class to instantiate
Abstract FactoryCreates families of related objects without specifying concrete classes
BuilderConstructs complex objects step by step
PrototypeCreates objects by cloning an existing instance

When to think creational: You find yourself using new in many places, or object construction is getting complex, conditional, or duplicated.


Structural Patterns — How objects are composed#

These patterns deal with object composition, creating relationships between objects to form larger structures.

PatternOne-liner
AdapterMakes incompatible interfaces work together
BridgeDecouples abstraction from implementation so both can evolve independently
CompositeTreats individual objects and groups of objects uniformly (tree structures)
DecoratorAdds responsibilities to objects dynamically without subclassing
FacadeProvides a simplified interface to a complex subsystem
FlyweightShares state to support large numbers of fine-grained objects efficiently
ProxyProvides a surrogate or placeholder to control access to another object

When to think structural: You're dealing with class explosions from inheritance, legacy system integration, or you need to add behaviour without modifying existing code.


Behavioral Patterns — How objects communicate#

These patterns characterise how classes and objects interact and distribute responsibility.

PatternOne-liner
Chain of ResponsibilityPasses requests along a chain of handlers
CommandEncapsulates a request as an object
IteratorProvides a way to sequentially access elements without exposing the underlying representation
MediatorDefines an object that encapsulates how objects interact
MementoCaptures and restores an object's internal state
ObserverNotifies dependents automatically when an object's state changes
StateLets an object alter its behavior when its internal state changes
StrategyDefines a family of algorithms and makes them interchangeable
Template MethodDefines the skeleton of an algorithm, deferring some steps to subclasses
VisitorLets you add further operations to objects without modifying them

When to think behavioral: You have complex conditional logic based on state, you need to decouple senders from receivers, or you want to add new operations to existing class hierarchies.


How to Pick the Right Pattern#

Ask yourself:

  1. What's the problem?

    • Object creation complexity → Creational
    • Class/object composition → Structural
    • Object interaction/algorithm → Behavioral
  2. What relationship are you modelling?

    • "I need exactly one" → Singleton
    • "I need compatible interfaces" → Adapter
    • "I need to add behaviour at runtime" → Decorator
    • "I need to change behaviour based on state" → State or Strategy
    • "I need to notify many objects of a change" → Observer
  3. What SOLID principle is being violated?

    • OCP (adding new types breaks existing code) → Factory, Strategy, Command
    • SRP (one class doing too much) → Facade, Decorator, Chain of Responsibility

Anti-Patterns to Avoid#

Anti-PatternBetter Alternative
Using Singleton for everythingDependency injection
Deep inheritance chainsDecorator or Strategy
Giant switch/if-else on typeFactory or Strategy
Client knowing too much about subsystemsFacade
Null checks everywhereNull Object

Summary#

Design patterns are a shared vocabulary. When you say "use the Strategy pattern here," every engineer on your team understands the intent, the trade-offs, and the structure — without reading the code. That's their real value.

Start with the problem, not the pattern. Applying a pattern for its own sake adds unnecessary complexity. Reach for patterns when they solve a concrete pain point you can name.

ReferencesLinks
Canonical ReferenceRefactoring Guru — Design Patterns
Original BookDesign Patterns by Gamma, Helm, Johnson, Vlissides (GoF, 1994)