Originally published on phpdesignpatterns.dev — part of the PHP design patterns course. View this lesson on the original site.
Behavioural patterns in plain English
Behavioural patterns are about how objects interact. Where creational patterns shape construction and structural patterns shape composition, behavioural patterns shape flow — who decides what runs, who tells whom, how state evolves, how a step in a process knows what comes next. This is the largest of the three families, and the one most directly tied to the day-to-day pain of business code.

Behavioural patterns in this course — how the families cluster (not a dependency diagram, just a map).
flowchart TB
subgraph vary["Variation and control flow"]
Strategy["Strategy<br/>+ policy interface, many implementations"]
TemplateMethod["Template Method<br/>+ fixed algorithm skeleton, hook methods"]
State["State<br/>+ behaviour bundle swaps with lifecycle"]
end
subgraph messages["Events, commands, pipelines"]
Observer["Observer<br/>+ dispatch typed events to N listeners"]
Command["Command<br/>+ DTO + handler + bus / queue"]
Pipeline["Pipeline / Middleware<br/>+ ordered steps, next callable"]
Chain["Chain of Responsibility<br/>+ first match wins, else delegate"]
Mediator["Mediator<br/>+ colleagues talk through coordinator"]
end
subgraph structure["Walking and operating on structure"]
Iterator["Iterator<br/>+ sequential access without exposing storage"]
Visitor["Visitor<br/>+ accept / visit double dispatch"]
Interpreter["Interpreter<br/>+ eval tree for a small grammar"]
end
subgraph rules["Rules and optional collaborators"]
Specification["Specification<br/>+ composable boolean predicates"]
NullObject["Null Object<br/>+ no-op implementation of same port"]
Memento["Memento<br/>+ opaque snapshot + caretaker stack"]
end
The pressure they relieve
You'll feel the need for a behavioural pattern when:
- A function does the same job in several different ways and the variation is captured in a long
if/switchchain. - An object's behaviour changes meaningfully as it moves between states —
Draft,Submitted,Approved,Rejected— and the rules are spreading intoifchains across the codebase. - A request needs to pass through a chain of small handlers, each one able to handle it, transform it, or pass it on.
- One part of the system needs to react to events in another, but you don't want them coupled directly.
- A complex algorithm has a fixed shape but a few replaceable steps, and you want to lock the shape while letting the steps vary.
- A piece of work needs to be captured as an object — undoable, queueable, loggable — instead of called as a method.
- You need to walk a structure and do something different at each kind of node, without bloating the nodes themselves.
- You want to express domain rules ("orders over £100 from new customers in the EU") as composable objects, not as scattered conditionals.
The patterns in this family
This course covers fourteen behavioural patterns:
- Strategy (chapter 3). A family of interchangeable behaviours behind one interface, chosen at the moment of use. The textbook fix for a long
if/switchchain where each branch is genuinely different work. - Observer (chapter 11). One object publishes events; many objects subscribe and react. Use it when a change in one place needs to fan out to several others without those others being known to the publisher.
- Command (chapter 12). Wrap a request as an object so it can be queued, logged, undone, or replayed. Use it for jobs, queued tasks, undo stacks, and CLI/HTTP action handlers.
- Pipeline / Middleware (chapter 13). Pass a value (a request, a domain object) through an ordered list of small steps, each free to transform it or short-circuit. Familiar from HTTP middleware in Laravel, Symfony, PSR-15.
- Chain of Responsibility (chapter 14). A request travels along a chain of handlers; each one decides whether to handle it or pass it on. Use it for layered authorisation, fallback lookups, or escalating support flows.
- Template Method (chapter 15). A base class defines the shape of an algorithm and leaves a few steps abstract; subclasses fill in only what changes. Use it sparingly — Strategy via composition is usually a better fit in modern PHP.
- State (chapter 16). Each state of an object is a class implementing the same interface; the object delegates to its current state and changes states explicitly. Use it when an entity's allowed actions depend strongly on which state it's in.
- Iterator (chapter 22). A standard way to walk a collection without exposing how the collection is stored. Mostly built-in to PHP via
Traversable/IteratorAggregate; the chapter focuses on when a hand-rolled iterator earns its keep. - Mediator (chapter 23). A central object coordinates a group of collaborators that would otherwise all talk to each other. Use it to break N-to-N coupling — chat rooms, form widgets, complex UI flows.
- Memento (chapter 24). Capture an object's internal state so it can be restored later, without exposing the internals. Use it for undo, snapshots, "save and restore" workflows.
- Visitor (chapter 25). Add new operations to a fixed structure of types without modifying the types. Use it when you have a stable hierarchy of node types and a growing set of operations over them.
- Interpreter (chapter 26). Express a small domain-specific language as a tree of evaluable nodes. Use it for rule engines, query languages, expression evaluators — and only when a real grammar is the right answer.
- Specification (chapter 28). Express domain rules ("eligible for next-day shipping") as composable objects with
and,or,not. Use it when business rules are complex, reused, and benefit from being named. - Null Object (chapter 28). A polymorphic stand-in for "no value" — a
GuestUser, aNoDiscount, an empty notifier — so callers don't have to scatterif (null)checks. Small, often-overlooked, and disproportionately useful.
What they have in common
Behavioural patterns all answer some version of "how does control move from here to there?" Strategy and State move it via polymorphism. Pipeline and Chain of Responsibility move it through a sequence. Observer and Mediator move it via messages. Command moves it by capturing it as a thing. Visitor moves it by inverting who knows what.
When you can name which behavioural pressure is hurting you — variation, sequencing, fan-out, capture, traversal — you've narrowed the choice to two or three patterns rather than fourteen.
When you don't need them
You don't need a behavioural pattern when:
- The variation is two short branches with no sign of growth.
- The "chain" is two steps and they sit fine inside one method.
- The "events" have one publisher and one subscriber and there's no plan for more.
The "when this is overkill" lesson in each chapter spells out the line. Trust it. Behavioural patterns are powerful precisely because they introduce indirection — and indirection always costs something.
Where to next
You now have the map: three families, every pattern in the catalogue, all of them answering specific kinds of pressure. From here on, every chapter is a single pattern, in roughly the order you're most likely to need them. Chapter 3 is Strategy, the most-reached-for behavioural pattern, and the one whose pain shape you have almost certainly seen in production code.
From PHP design patterns — Introduction to design patterns