Chapter 01
How to use patterns
What a design pattern is, the three families in the Gang of Four catalogue, and the two principles most patterns are built on.
Design pattern
Also called GoF, Gang of Four, software design pattern
- What
- A named, reusable solution to a design problem that keeps recurring in object-oriented code. The 1994 book by Gamma, Helm, Johnson and Vlissides catalogued 23 of them.
- Why
- A shared name ("put a Strategy here") saves a paragraph of explanation in every design discussion and code review.
Watch out
Treating patterns as code to copy; each is a shape to adapt, and often a few lines in a modern language.
Creational, structural, behavioural
Also called pattern categories, three families
- What
- Creational patterns control how objects are made (5). Structural patterns control how objects are composed (7). Behavioural patterns control how objects share work and communicate (11).
- Why
- Knowing the family narrows the search: a construction problem is rarely solved by a behavioural pattern.
Program to an interface
Also called depend on abstractions, interface over implementation
- What
- Write code against what an object can do (an interface or abstract type), not which concrete class it is.
- Why
- Most patterns exist to make this possible, so implementations can be swapped, faked in tests and extended.
interface Notifier { send(to: string, msg: string): void; }
class SignupService {
constructor(private notifier: Notifier) {}
register(email: string) {
this.notifier.send(email, 'Welcome');
}
}Composition over inheritance
Also called has-a over is-a, favour composition
- What
- Build behaviour by holding other objects and delegating to them, rather than by deep subclass chains.
- Why
- Composition can change at run time and avoids the rigid, fragile hierarchies that inheritance tends to grow.
- Example
- Instead of
FlyingDuck,RubberDuckandFlyingRubberDucksubclasses, aDuckholds aFlyBehaviourobject.
Reading pattern diagrams
Also called UML class diagram, UML
- What
- Pattern books draw UML class diagrams: a box per class, a hollow triangle arrow for "implements or extends", a plain arrow for "uses", and a diamond for "holds or owns".
- Why
- Every catalogue and most design documents use this notation, so reading it is a small skill with a big payoff.
<<interface>> Notifier
^ ^
| | hollow arrow: implements
EmailNotifier SmsNotifier
SignupService ----> Notifier plain arrow: usesWhen not to use a pattern
Also called over-engineering, pattern fever, YAGNI
- What
- A pattern adds classes and indirection. Use one when the problem it solves is present now or clearly coming, not in case it might be.
- Why
- Unneeded factories and abstract layers make simple code hard to follow and slow to change.
Watch out
Wrapping a single implementation in an interface, a factory and a builder for a feature with one caller.
Go deeper