Design Patterns: Elements of Reusable Object-Oriented Software, by the four authors known as the Gang of Four, catalogued 23 recurring solutions to object-oriented design problems. Published in 1994, it gave developers a shared vocabulary that's still in daily use, and nowhere more than in Java.
Three families of patterns
- Creational patterns control how objects are made: Factory Method, Abstract Factory, Builder, Prototype and Singleton.
- Structural patterns compose classes and objects into larger structures: Adapter, Bridge, Composite, Decorator, Façade, Flyweight and Proxy.
- Behavioural patterns describe how objects communicate: Strategy, Observer, Command, Template Method, Iterator, State, Visitor and others.
Two principles underneath
Before the catalogue, the book sets out two principles that matter more than any single pattern. Program to an interface, not an implementation. And favour object composition over class inheritance. Most of the patterns are ways of applying those two ideas to specific problems.
Program to an interface, not an implementation.
Patterns in everyday Java
Java's standard library and its major frameworks are full of these patterns. I/O streams are decorators. Spring's proxies, templates and factories come straight from the catalogue. Listeners are observers, and iterators are, well, iterators. Knowing the patterns makes framework code far easier to read.
Some patterns have aged. Modern Java's lambdas make Strategy and Command much lighter, and Singleton is now usually better handled by a dependency injection container. The ideas still hold even where the implementations have changed.
Key ideas
Program to an interface.
Depending on abstractions rather than concrete classes keeps designs flexible and testable.
Favour composition over inheritance.
Assembling behaviour from objects is more flexible than locking it into a class hierarchy.
Patterns are a vocabulary.
Saying 'use a decorator here' communicates a whole design in three words.
Don't force patterns.
A pattern applied where the problem doesn't exist only adds complexity.
Modern Java changes the shape, not the idea.
Lambdas and dependency injection simplify many patterns, but the underlying design thinking is the same.
My take
The book that taught a generation of us how to talk about design.
I first read this early in my Java career, and it changed how I read other people's code. Suddenly the frameworks I used every day made sense: they were built from these patterns.
It's not an easy read, and the examples are in C++ and Smalltalk. Read the introduction and the case study carefully, then treat the catalogue as a reference. Combined with a modern Java book, it's still one of the best investments a developer can make.
Who should read it
- Java developers moving from writing code to designing it.
- Engineers who want to understand how frameworks like Spring are built.
- Reviewers who want a shared vocabulary for design feedback.