Recipes all share a format: ingredients, prep time, steps, serving suggestions. Design patterns are documented the same way. Once you know the template, you can pick up any pattern from a book or website quickly and know where to look for what you need.
The anatomy of a pattern description#
At its core, every pattern answers three questions:
| Part | Question it answers |
|---|---|
| Problem | What pain does it solve? |
| Solution | What's the blueprint? |
| Consequences | What are the trade-offs? |
Read the problem first. Without it, patterns feel like solutions looking for problems.
The Gang of Four book expands this into a fuller template:
| Section | What it tells you |
|---|---|
| Name | The handle you use in conversation ("let's use a Singleton") |
| Classification | Creational, Structural or Behavioral |
| Intent | One or two sentences: what the pattern does (its elevator pitch) |
| Also known as | Other names for the same idea |
| Motivation | A concrete scenario showing the problem |
| Applicability | Situations where the pattern fits |
| Structure | A class diagram of the participants |
| Participants / Collaborations | Each class's role and how they work together |
| Consequences | Benefits, costs and trade-offs |
| Implementation / Sample code | Tips, pitfalls and code |
| Known uses | Real systems that use it |
| Related patterns | Similar or complementary patterns |
Worked example: Observer#
Here is the template filled in for one pattern.
Classification: Behavioral.
Intent: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
Also known as: Publish-Subscribe, Dependents, event listener.
Motivation. A weather station collects temperature and humidity. Several displays need the data: current conditions, statistics, forecast, a mobile app. The naive design has the station call each one:
weather_station.update_current_display()
weather_station.update_stats_display()
weather_station.update_forecast()
weather_station.update_mobile_app()
The station now knows every display (tight coupling), adding a display means editing the station, and you can't add or remove displays at runtime.
Structure. The station holds a list of observers and calls update() on each one; every display implements the same interface.
Applicability. Use Observer when:
- A change to one object requires changing others.
- You don't know in advance how many objects need to react.
- An object should notify others without knowing who they are.
Real-world examples: newsletter subscriptions, YouTube subscribers, stock price alerts, GUI event handling.
Consequences.
| Pros | Cons |
|---|---|
| Loose coupling between subject and observers | Notification order is not something you should rely on |
| Observers can be added or removed at runtime | Forgotten observers cause memory leaks |
| Subject doesn't know concrete observer classes | Cascading updates can be hard to debug |
| Supports broadcast communication | Many observers means slower notifications |
Implementation.
from abc import ABC, abstractmethod
class Observer(ABC):
@abstractmethod
def update(self, temp: float, humidity: float) -> None: ...
class Subject(ABC):
@abstractmethod
def attach(self, o: Observer) -> None: ...
@abstractmethod
def detach(self, o: Observer) -> None: ...
@abstractmethod
def notify_observers(self) -> None: ...
class WeatherStation(Subject):
def __init__(self) -> None:
self._observers: list[Observer] = []
self._temperature = 0.0
self._humidity = 0.0
def attach(self, o: Observer) -> None:
self._observers.append(o)
def detach(self, o: Observer) -> None:
self._observers.remove(o)
def set_measurements(self, t: float, h: float) -> None:
self._temperature = t
self._humidity = h
self.notify_observers() # every state change triggers a broadcast
def notify_observers(self) -> None:
for o in self._observers:
o.update(self._temperature, self._humidity)
Known uses. GUI toolkits' event callbacks (Tkinter's bind), Python's logging handlers, JavaScript EventEmitter and DOM events, .NET events and delegates, the model-notifies-views part of MVC.
Related patterns. Mediator centralizes complex communication; an event bus is a centralized variant of Observer.
Which sections to read, and when#
Which sections matter most depends on why you're reading.
| You are... | Read first |
|---|---|
| Learning a pattern | Intent → Motivation → Structure → Implementation |
| Evaluating whether it fits | Applicability → Consequences → Known uses |
| Implementing it | Implementation → Consequences (what to watch out for) → Related patterns |
What to learn first#
You don't need all 23 patterns at once. Learn them in roughly this order:
| Tier | Patterns |
|---|---|
| Essential | Singleton, Factory Method, Observer, Strategy, Decorator |
| Very useful | Adapter, Builder, Command, Facade, Iterator |
| Good to know | Template Method, State, Proxy, Composite, Abstract Factory |
Key takeaways#
- Every pattern description answers: what problem, what solution, what trade-offs.
- The intent is the one-line summary; the motivation is the problem in context.
- Read applicability and consequences before deciding to use a pattern.
- Start with the essential five; most real code uses a handful of patterns over and over.