Behavioural Patterns#
flowchart LR
C[Caller]
S([Strategy])
O([Observer])
ST([State])
CMD([Command])
CH([Chain of Resp.])
T([Template Method])
C --> S
C --> O
C --> ST
C --> CMD
C --> CH
C --> T
classDef p fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef s fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
class C p;
class S,O,ST,CMD,CH,T s;
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class C,S,O,ST,CMD,CH,T service;
How objects communicate and change behaviour at runtime: Strategy, Observer, State, Command, Chain of Responsibility, Template Method, Iterator, Mediator, Visitor, Memento.
Strategy - pick an algorithm at runtime#
classDiagram
class Context {
-strategy: Strategy
+setStrategy(Strategy)
+execute()
}
class Strategy {
<<interface>>
+run()
}
class FastStrategy
class CheapStrategy
Strategy <|.. FastStrategy
Strategy <|.. CheapStrategy
Context o--> Strategy
Used by pricing engines, sort algorithms, payment routing, retry policies, ranker variants.
Observer - many subscribers react to changes in one subject#
classDiagram
class Subject {
-observers: Observer[]
+attach(Observer)
+detach(Observer)
+notify()
}
class Observer {
<<interface>>
+update()
}
class EmailNotifier
class AuditLogger
Subject o--> Observer
Observer <|.. EmailNotifier
Observer <|.. AuditLogger
Foundation of event-driven UIs, pub/sub, MVC, reactive streams. At the system level → see pub-sub-pattern.
State - encapsulate state-dependent behaviour#
stateDiagram-v2
[*] --> Idle
Idle --> Selecting : coin inserted
Selecting --> Dispensing : item chosen
Dispensing --> Idle : delivered
Selecting --> Idle : cancel
Each state is its own class; the context holds a reference to the current state and forwards method calls. The state object can swap itself out. Used by the Vending Machine, ATM, Elevator LLD designs in this site.
Command - turn a request into an object#
classDiagram
class Command {
<<interface>>
+execute()
+undo()
}
class Invoker {
-history: Command[]
+submit(Command)
+undoLast()
}
class TurnOnLight
class TurnOffLight
Command <|.. TurnOnLight
Command <|.. TurnOffLight
Invoker o--> Command
Use for undo/redo, queueing, macro recording, transactional UIs. Underpins the Chess engine move history.
Chain of Responsibility - pass a request along until handled#
flowchart LR
R[Request]
A[Handler A<br/>auth]
B[Handler B<br/>validate]
C[Handler C<br/>execute]
R --> A --> B --> C
classDef s fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef p fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
class A,B,C s;
class R p;
classDef client fill:#dbeafe,stroke:#1e40af,stroke-width:1px,color:#0f172a;
classDef edge fill:#cffafe,stroke:#0e7490,stroke-width:1px,color:#0f172a;
classDef service fill:#fef3c7,stroke:#92400e,stroke-width:1px,color:#0f172a;
classDef datastore fill:#fee2e2,stroke:#991b1b,stroke-width:1px,color:#0f172a;
classDef cache fill:#fed7aa,stroke:#9a3412,stroke-width:1px,color:#0f172a;
classDef queue fill:#ede9fe,stroke:#5b21b6,stroke-width:1px,color:#0f172a;
classDef compute fill:#d1fae5,stroke:#065f46,stroke-width:1px,color:#0f172a;
classDef storage fill:#e5e7eb,stroke:#374151,stroke-width:1px,color:#0f172a;
classDef external fill:#fce7f3,stroke:#9d174d,stroke-width:1px,color:#0f172a;
classDef obs fill:#f3e8ff,stroke:#6b21a8,stroke-width:1px,color:#0f172a;
class R,A,B,C service;
Each link can handle, modify, short-circuit, or forward. HTTP middleware (Express, Rack, ASP.NET), logger appender chains, API gateway plugins.
Template Method - fixed skeleton, customisable steps#
abstract class ReportGenerator {
public final Report build() { // template method
var d = fetch();
var s = aggregate(d);
return render(s);
}
protected abstract Data fetch();
protected abstract Summary aggregate(Data d);
protected abstract Report render(Summary s);
}
The base class controls the algorithm shape; subclasses fill in the steps.
Iterator - traverse without exposing internals#
Already built into every modern language. The pattern matters when you implement a custom collection (e.g. paginated API, lazy stream).
Mediator - central object decouples peers#
Used by chat rooms (one room mediates participants), form controllers, air-traffic-control style domains.
Visitor - operations external to a class hierarchy#
Useful when you have a stable class hierarchy and want to add new operations without modifying the hierarchy each time (linters, code formatters, optimisers over ASTs).
Memento - capture and restore state#
Pair with Command for undo/redo. Save just enough state to roll back later. Chess engines, text editors.
Where these show up in this site#
- Notification system: Strategy (pick channel: push / sms / email).
- Web crawler / Job scheduler: Observer (workers subscribe to a frontier queue).
- Vending Machine / ATM / Elevator: State machine + State pattern.
- Chess / Snake & Ladders / Tic-tac-toe: Command (move) + Memento (history).
- API gateway / Logger framework / HTTP servers: Chain of Responsibility.
- Search ranker / Pricing engine / Auction matching: Strategy.
- Pub/Sub at scale: Observer scaled across services.
Glossary & fundamentals#
Concepts referenced in this design. Each row links to its canonical page; the tag column shows whether it is a high-level (HLD) or low-level (LLD) concept.
| Tag | Concept | What it is | Page |
|---|---|---|---|
HLD |
API gateway / BFF | single ingress, auth, rate limit, routing | api-gateway |
HLD |
Pub/Sub & message brokers | topics, consumer groups, delivery semantics | pub-sub-pattern |
HLD |
Idempotency & retries | safe re-execution, backoff + jitter | idempotency-retries |
LLD |
State machines | FSM, HSM, transitions, guards | state-machines |
LLD |
Async models | futures / async-await / coroutines / actors | async-models |
LLD |
OOP pillars | encapsulation, abstraction, inheritance, polymorphism | oop-pillars |
LLD |
Behavioural patterns | Strategy, Observer, State, Command, Chain | behavioral-patterns |
Quick reference#
Quick chooser#
| Goal | Pattern |
|---|---|
| Swap algorithm at runtime | Strategy |
| Many parts react to a change | Observer |
| Different behaviour per state, same interface | State |
| Undo / queue / log / replay a request | Command |
| Pipeline of optional handlers | Chain of Responsibility |
| Fixed algorithm shape, varying steps | Template Method |
| Walk a custom collection | Iterator |
| Decouple noisy n-to-n peers | Mediator |
| New operations over a stable hierarchy | Visitor |
| Save / restore snapshots | Memento |
Strategy vs Template Method#
- Strategy: composition (the algorithm is an object you swap).
- Template Method: inheritance (the algorithm shape lives on the base class).
Observer vs Pub/Sub#
- Observer: in-process, often synchronous, observers know the subject.
- Pub/Sub: a broker decouples publishers and subscribers across processes / hosts.
State vs strategy#
Same class shape; intent differs. State = the object's mode dictates which Strategy is active; transitions are part of the model.
Refs#
- GoF chapters on behavioural patterns.
- Head First Design Patterns - beginner-friendly.
- Refactoring (Fowler) - pragmatic application.
FAQ#
What are behavioral design patterns?#
Patterns that describe how objects interact and assign responsibilities. They cover communication, control flow, and algorithm choice, including Strategy, Observer, State, and Command.
Strategy vs State, what is the difference?#
Strategy swaps interchangeable algorithms chosen by the caller. State swaps behavior based on the object's internal state, with transitions managed by the state objects themselves.
When should I use the Observer pattern?#
When multiple objects need to react to changes in one source without tight coupling, like UI bindings or event-driven domain notifications. Avoid it if listeners require strict ordering.
What problem does Chain of Responsibility solve?#
It lets a request pass through a sequence of handlers until one handles it. Common uses are middleware pipelines, validation chains, and event filtering.
What is the Command pattern good for?#
Encapsulating an action and its parameters as an object so it can be queued, logged, undone, or retried. It is the basis of undo/redo and job queue libraries.
Related Topics#
- Creational Patterns: companion creational patterns often combined with behavioral ones
- Structural Patterns: structural patterns that complement behavioral design
- SOLID Principles: OCP and SRP directly motivate the behavioral pattern suite
Further reading#
Curated, high-credibility sources for going deeper on this topic.