LearningTree

Design Patterns

All 20 Gang of Four design patterns with UML class diagrams, detailed descriptions, and implementations in Java, Python & C# — organised by Creational, Structural, and Behavioral categories.

Design patterns are reusable solutions to recurring design problems. The Gang of Four (GoF) catalogued 23 patterns in three categories. This page covers the 20 most essential patterns with UML diagrams and tri-language code examples.

CategoryPatternsFocus
Creational (5)Singleton, Factory Method, Abstract Factory, Builder, PrototypeObject creation mechanisms
Structural (7)Adapter, Bridge, Composite, Decorator, Facade, Flyweight, ProxyObject composition & structure
Behavioral (8)Observer, Strategy, Command, Template Method, Chain of Responsibility, State, Mediator, VisitorObject communication & responsibility
01
Chapter One · Object Creation

Creational Patterns

Creational patterns abstract the instantiation process — they make a system independent of how its objects are created, composed, and represented.

📦

Singleton

  • One instance, global access
🏭

Factory Method

  • Subclass-driven creation
🏗

Abstract Factory

  • Product family creation
🧱

Builder

  • Step-by-step construction
🐑

Prototype

  • Clone-based instantiation
Singleton
Ensures a class has only one instance and provides a global point of access to it.

When to use: Use when exactly one instance is needed — loggers, config managers, thread pools, caches.

ComponentRole
Static InstanceHolds the single instance
Private ConstructorPrevents external instantiation
getInstance()Returns the sole instance
Singleton — Class Diagram
Singleton - instance: Singleton - Singleton() + getInstance(): Singleton + operation()
Factory Method
Defines an interface for creating objects, letting subclasses decide which class to instantiate.

When to use: Use when a class cannot anticipate the type of objects it needs to create.

ComponentRole
CreatorDeclares the factory method
ConcreteCreatorOverrides factory method
ProductInterface for objects
ConcreteProductSpecific implementation
Factory Method — Class Diagram
Creator abstract + factoryMethod(): Product Product interface ConcreteCreator + factoryMethod() ConcreteProduct + operation()
Abstract Factory
Provides an interface for creating families of related objects without specifying concrete classes.

When to use: Use when products come in families that must be used together (e.g. cross-platform UI).

ComponentRole
AbstractFactoryInterface for creating families
ConcreteFactoryCreates specific family
AbstractProductInterface per product type
ClientUses only abstract interfaces
Abstract Factory — Class Diagram
GUIFactory interface + createButton() + createWindow() WinFactory creates WinButton, WinWindow MacFactory creates MacButton, MacWindow
Builder
Separates the construction of a complex object from its representation, allowing step-by-step creation.

When to use: Use when constructing complex objects with many optional parameters.

ComponentRole
BuilderStep-by-step interface
ConcreteBuilderBuilds the product
DirectorOrchestrates order
ProductComplex object built
Builder — Class Diagram
Director + construct(builder) Builder interface + buildPart() + getResult() ConcreteBuilder builds Product
Prototype
Creates new objects by cloning an existing instance, avoiding costly creation from scratch.

When to use: Use when object creation is expensive or you need copies with slight variations.

ComponentRole
PrototypeInterface with clone()
ConcretePrototypeImplements cloning
ClientRequests clones
Prototype — Class Diagram
Prototype + clone(): Prototype
📋 Chapter 1 — Summary
  • Singleton — one instance, global access (use sparingly)
  • Factory Method — subclasses decide which class to instantiate
  • Abstract Factory — create families of related objects
  • Builder — construct complex objects step by step
  • Prototype — clone existing objects to avoid costly creation
02
Chapter Two · Object Composition

Structural Patterns

Structural patterns deal with object composition — how classes and objects are assembled to form larger structures while keeping them flexible and efficient.

🔌

Adapter

  • Interface conversion
🌉

Bridge

  • Abstraction / impl split
🌲

Composite

  • Tree structures
🎁

Decorator

  • Dynamic behaviour
🏠

Facade

  • Simple interface
🩶

Flyweight

  • Memory sharing
🛡

Proxy

  • Access control
Adapter
Converts the interface of a class into another interface clients expect.

When to use: Use when you want to use an existing class but its interface is incompatible.

ComponentRole
TargetInterface client expects
AdapterBridges target and adaptee
AdapteeExisting incompatible class
Adapter — Class Diagram
Target interface Adapter + request() Adaptee + specificRequest()
Bridge
Decouples an abstraction from its implementation so they can vary independently.

When to use: Use when you want to avoid a permanent binding between abstraction and implementation.

ComponentRole
AbstractionHigh-level interface
ImplementorLow-level interface
RefinedAbstractionExtended abstraction
ConcreteImplementorSpecific implementation
Bridge — Class Diagram
Abstraction - impl: Implementor + operation()
Composite
Composes objects into tree structures to represent part-whole hierarchies.

When to use: Use when clients should treat individual objects and compositions uniformly.

ComponentRole
ComponentCommon interface
LeafPrimitive element
CompositeHas children components
Composite — Class Diagram
Component + operation() + add(c) + remove(c)
Decorator
Attaches additional responsibilities to an object dynamically without altering its structure.

When to use: Use to add behaviour to objects without subclass explosion.

ComponentRole
ComponentInterface
ConcreteComponentBase object
DecoratorWraps component
ConcreteDecoratorAdds behaviour
Decorator — Class Diagram
Decorator - wrapped: Component + operation()
Facade
Provides a simplified interface to a complex subsystem.

When to use: Use to reduce coupling between clients and a complex library or subsystem.

ComponentRole
FacadeSimple unified interface
Subsystem classesComplex internal components
Facade — Class Diagram
Facade - subsystemA - subsystemB + simpleOperation()
Flyweight
Shares common state among many objects to reduce memory usage.

When to use: Use when many similar objects consume too much memory (text editors, game particles).

ComponentRole
FlyweightShared intrinsic state
FlyweightFactoryManages shared instances
ClientProvides extrinsic state
Flyweight — Class Diagram
Flyweight - intrinsicState + operation(extrinsic)
Proxy
Provides a surrogate or placeholder for another object to control access.

When to use: Use for lazy loading, access control, logging, or caching.

ComponentRole
SubjectCommon interface
RealSubjectActual object
ProxyControls access to real subject
Proxy — Class Diagram
Proxy - realSubject: Subject + request()
📋 Chapter 2 — Summary
  • Adapter — convert one interface to another
  • Bridge — separate abstraction from implementation
  • Composite — treat individual and composite objects uniformly
  • Decorator — add behaviour without subclassing
  • Facade — simplify complex subsystem interfaces
  • Flyweight — share state to reduce memory
  • Proxy — control access to an object
03
Chapter Three · Communication

Behavioral Patterns

Behavioral patterns are concerned with communication between objects — how responsibilities are assigned and how algorithms are encapsulated.

🔔

Observer

  • Event notification

Strategy

  • Swap algorithms
📜

Command

  • Encapsulate requests
📋

Template Method

  • Algorithm skeleton

Chain of Resp.

  • Handler pipeline
🚦

State

  • State-based behaviour
📡

Mediator

  • Central coordination
🧑‍💼

Visitor

  • Add operations
Observer
Defines a one-to-many dependency so that when one object changes state, all dependents are notified.

When to use: Use for event systems, pub/sub, reactive UI updates.

ComponentRole
SubjectMaintains observer list
ObserverInterface for notification
ConcreteObserverReacts to changes
Observer — Class Diagram
Subject - observers: List + attach(o) + notify()
Strategy
Defines a family of algorithms, encapsulates each one, and makes them interchangeable.

When to use: Use when you need to switch algorithms at runtime (sorting, payment, routing).

ComponentRole
StrategyAlgorithm interface
ConcreteStrategySpecific algorithm
ContextUses a strategy
Strategy — Class Diagram
Context - strategy: Strategy + execute()
Command
Encapsulates a request as an object, allowing parameterization and queuing.

When to use: Use for undo/redo, task queuing, macro recording.

ComponentRole
CommandInterface with execute()
ConcreteCommandBinds receiver to action
InvokerTriggers command
ReceiverPerforms the work
Command — Class Diagram
Command + execute() + undo()
Template Method
Defines the skeleton of an algorithm, deferring some steps to subclasses.

When to use: Use when multiple classes share the same algorithm but differ in specific steps.

ComponentRole
AbstractClassTemplate with hook methods
ConcreteClassOverrides specific steps
Template Method — Class Diagram
AbstractClass + templateMethod() # step1() # step2()
Chain of Responsibility
Passes a request along a chain of handlers until one handles it.

When to use: Use for middleware pipelines, event bubbling, approval workflows.

ComponentRole
HandlerInterface with next handler
ConcreteHandlerHandles or passes along
Chain of Responsibility — Class Diagram
Handler - next: Handler + handle(request)
State
Allows an object to alter its behaviour when its internal state changes.

When to use: Use when an object has many conditional behaviours that depend on its state.

ComponentRole
ContextMaintains current state
StateInterface for behaviours
ConcreteStateState-specific behaviour
State — Class Diagram
Context - state: State + request()
Mediator
Defines an object that encapsulates how a set of objects interact, promoting loose coupling.

When to use: Use when many objects communicate in complex ways (chat rooms, UI components).

ComponentRole
MediatorCoordination interface
ConcreteMediatorImplements coordination
ColleagueCommunicates via mediator
Mediator — Class Diagram
Mediator + notify(sender, event)
Visitor
Lets you add new operations to existing classes without modifying them.

When to use: Use when you need to perform many unrelated operations on an object structure.

ComponentRole
VisitorDeclares visit methods
ConcreteVisitorImplements operations
ElementAccepts visitors
Visitor — Class Diagram
Visitor + visitA(ElementA) + visitB(ElementB)
📋 Chapter 3 — Summary
  • Observer — notify dependents when state changes
  • Strategy — swap algorithms at runtime
  • Command — encapsulate requests as objects (undo/redo)
  • Template Method — define algorithm skeleton, defer steps
  • Chain of Responsibility — pass request along handler chain
  • State — change behaviour when state changes
  • Mediator — centralise complex communication
  • Visitor — add operations without modifying classes
Summary — 20 Design Patterns at a Glance
01 · Creational

Object Creation

  • Singleton — one global instance
  • Factory Method — subclass decides
  • Abstract Factory — product families
  • Builder — step-by-step
  • Prototype — clone instances
02 · Structural

Object Composition

  • Adapter — interface conversion
  • Bridge — abstraction split
  • Composite — tree structures
  • Decorator — dynamic behaviour
  • Facade — simple interface
  • Flyweight — memory sharing
  • Proxy — access control
03 · Behavioral

Communication

  • Observer — event notification
  • Strategy — swap algorithms
  • Command — encapsulate requests
  • Template Method — algorithm skeleton
  • Chain of Resp. — handler pipeline
  • State — state-based behaviour
  • Mediator — central coordination
  • Visitor — add operations
Design Patterns · LearningTree · 2026