Loading content...
Before the Gang of Four, patterns existed as informal, ad-hoc descriptions passed between developers. What made the GoF book transformative wasn't just the identification of patterns—it was the systematic format for documenting them. This format transformed patterns from vague notions into precise, actionable design tools.
The GoF documentation format has become a template for the entire patterns community. When you read a pattern description in a book, article, or documentation, you'll encounter variations of the structure they established. Understanding this format is essential for two reasons: it helps you extract maximum value from pattern documentation, and it prepares you to communicate your own design solutions in a structured way.
In this page, we'll dissect the GoF pattern template, examining each section's purpose and how to use it effectively.
By the end of this page, you will understand every section of the GoF pattern documentation format, why each section matters, how the sections work together to create a complete pattern picture, and how to read patterns efficiently depending on your needs—whether learning, evaluating, or implementing.
Pattern documentation serves multiple audiences with different needs:
A standardized format allows each audience to navigate directly to the information they need. A developer evaluating whether to use the Observer pattern can read Intent and Applicability without wading through implementation details. An implementer already committed to Observer can skip to Structure and Sample Code.
The format also ensures completeness. By requiring authors to address Intent, Motivation, Applicability, Structure, Participants, Collaborations, Consequences, Implementation, Sample Code, Known Uses, and Related Patterns, the format prevents patterns from being documented as "just an idea." Every pattern must be grounded in concrete structure, real-world usage, and explicit consideration of trade-offs.
| Section | Purpose | Key Questions Answered |
|---|---|---|
| Intent | One-sentence pattern summary | What does this pattern do? |
| Also Known As | Alternative names | What else is this called? |
| Motivation | Illustrative scenario | Why would I need this? |
| Applicability | When to use the pattern | Is this right for my problem? |
| Structure | Class/object diagrams | How is it organized? |
| Participants | Classes/objects and their responsibilities | What are the roles? |
| Collaborations | How participants interact | How do the parts work together? |
| Consequences | Trade-offs and results | What do I gain and lose? |
| Implementation | Pitfalls and techniques | How do I build this correctly? |
| Sample Code | Code examples | What does it look like in code? |
| Known Uses | Real-world examples | Where has this been used successfully? |
| Related Patterns | Alternatives and complements | What else should I consider? |
Think of the pattern format as a contract between author and reader. The author commits to providing complete, structured information. The reader knows exactly where to find each type of information. This contract makes pattern literature navigable and consistent across authors, books, and domains.
Intent: The Pattern's Elevator Pitch
The Intent section is a short statement—usually one or two sentences—that describes what the pattern does and what particular design issue or problem it addresses. This is the pattern's "elevator pitch."
A well-written intent serves as a quick filter. Reading intents, you can rapidly scan a catalog and identify patterns worth investigating further. The intent should capture the pattern's essence without unnecessary detail.
Examples of Intent statements from the GoF book:
Strategy: "Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it."
Observer: "Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically."
Decorator: "Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality."
Notice how each intent captures both the what (what the pattern does) and the why (what benefit it provides).
Also Known As: Aliases and Alternative Names
Patterns often have multiple names, either from different communities, historical evolution, or slight variations. The Also Known As section lists these alternative names.
For example:
Knowing aliases is practically important. When reading code or documentation that uses a different name, you'll recognize the pattern. When searching for information, you'll know what alternative terms to try.
The patterns community evolved before standardized terminology. Smalltalk developers called things differently than C++ developers. Academic papers used different terms than industry practice. The GoF book helped standardize vocabulary, but aliases persist—and knowing them helps you navigate older literature and diverse codebases.
Making Abstract Concepts Concrete
The Motivation section presents a scenario that illustrates a design problem and how the pattern's structure solves it. This is where the pattern comes alive—where abstract structure becomes concrete solution.
Motivation sections typically:
Describe a realistic problem scenario — Not a toy example, but a situation readers recognize. The GoF book uses examples from document editors, graphical frameworks, and compilers.
Show why naive solutions fail — Demonstrate that obvious approaches lead to problems: inflexibility, tight coupling, code duplication, etc.
Introduce the pattern as a solution — Show how applying the pattern addresses the problems identified.
Walk through the solution — Explain how the pattern's structure resolves the forces at play.
Example: The Strategy Pattern's Motivation
The GoF book motivates Strategy with a text composition scenario. A document editor needs to break lines of text. Different algorithms exist (simple, TeX-quality, array-based), and the editor should support multiple algorithms without hard-coding each one.
The naive approach—embedding line-breaking algorithms directly in the composition class with conditionals—creates problems:
The Strategy pattern solves this by:
When learning a new pattern, read the Motivation section carefully. Understanding why a pattern exists—what problem drove its creation—is more valuable than memorizing its structure. Structure can be looked up; understanding takes internalization.
Good Motivations Resonate
The best motivation scenarios make you say, "I've faced that exact problem!" or "That's going to happen to me soon." When a motivation resonates with your experience, the pattern becomes not an abstract concept but a tool you're eager to apply.
This is why the GoF chose scenarios from real systems they had built or studied. The document editor, the graphics toolkit, the compiler—these weren't invented for the book. They were actual systems where the patterns had proven their worth.
The Pattern's Entry Criteria
The Applicability section provides explicit guidance on when to use the pattern. It lists the situations in which the pattern applies—the conditions that, when true, suggest this pattern as a solution.
Applicability statements are typically phrased as conditions:
Strategy Applicability (from GoF):
Observer Applicability (from GoF):
Just because your situation matches a pattern's applicability doesn't mean you must use the pattern. You need to weigh the pattern's consequences (benefits and costs) against your specific context. Applicability identifies candidates; judgment selects winners.
These three sections together describe the pattern's static and dynamic aspects—what the parts are, how they're organized, and how they interact.
Structure: The Pattern's Architecture
The Structure section presents a graphical representation of the pattern using class and/or object diagrams. In the original GoF book, this used OMT (Object Modeling Technique) notation, a precursor to UML. Modern pattern documentation typically uses UML.
The structure diagram shows:
A single diagram captures what would take paragraphs to describe. Study the structure diagram carefully—it's the pattern's blueprint.
Participants: Roles and Responsibilities
The Participants section lists every class and/or object in the pattern's structure, describing each one's responsibilities. This is where you learn what each role does.
Example: Observer Pattern Participants
Subject — Knows its observers. Any number of Observer objects may observe a Subject. Provides an interface for attaching and detaching Observer objects.
Observer — Defines an updating interface for objects that should be notified of changes in a Subject.
ConcreteSubject — Stores state of interest to ConcreteObservers. Sends notification to its observers when its state changes.
ConcreteObserver — Maintains a reference to a ConcreteSubject object. Stores state that should stay consistent with the Subject's. Implements the Observer updating interface to keep its state consistent with the Subject.
Notice how each participant has clear, bounded responsibilities. This clarity is what makes patterns reusable—you can identify which role each class in your system should play.
Collaborations: Dynamic Behavior
The Collaborations section describes how participants work together to carry out their responsibilities. It focuses on runtime behavior—the sequence of messages and interactions that achieve the pattern's purpose.
Collaborations are often illustrated with sequence diagrams or interaction diagrams. Where Structure shows static organization, Collaborations shows dynamic behavior.
Example: Observer Pattern Collaborations
ConcreteSubject notifies its observers whenever a change occurs that could make its observers' state inconsistent with its own.
After being informed of a change in ConcreteSubject, a ConcreteObserver object may query the subject for information. ConcreteObserver uses this information to reconcile its state with that of the subject.
This collaboration reveals the push-pull dynamic central to Observer: the subject pushes notification, observers pull specific data they need.
When implementing a pattern, understand the Structure first—get the classes and relationships right. Then study Collaborations to understand the runtime dynamics. A common mistake is getting the structure right but implementing the collaborations incorrectly—the classes exist but don't interact properly.
Every Pattern Has a Price
The Consequences section is perhaps the most important for decision-making. It describes the results and trade-offs of applying the pattern—both benefits and liabilities.
Patterns are not free lunches. Each pattern trades one set of design concerns for another. Understanding consequences prevents you from being surprised by the costs of a pattern after you've committed to it.
Consequences typically address:
Notice the Duality
Look at the Observer consequences above. "Unexpected updates" appears as both a benefit and a liability. This illustrates an important pattern truth: the same characteristic can be good or bad depending on context.
Consequences help you reason about whether the trade-offs are acceptable for your specific situation.
Before committing to a pattern, read its Consequences section carefully. Ask yourself: Can I accept these trade-offs? Is the flexibility worth the complexity? Are the liabilities tolerable in my context? If consequences feel uncomfortable, consider alternative patterns.
Where the Rubber Meets the Road
The Implementation section provides practical guidance for implementing the pattern—pitfalls to avoid, techniques to consider, and language-specific considerations. This section bridges the gap between abstract pattern structure and working code.
Implementation sections typically cover:
Example: Observer Implementation Considerations
Mapping subjects to observers — What data structure should subjects use to store observers? A linked list works but may be slow for many observers. A hash table optimizes lookup but uses more memory.
Observing more than one subject — If an observer follows multiple subjects, it must know which subject changed. The update interface may need to pass the subject as a parameter.
Who triggers the update? — Should the subject automatically notify observers after each state change, or should clients explicitly trigger notifications after a batch of changes?
Dangling references to deleted subjects — What happens if a subject is deleted while observers still reference it? Solutions include having subjects notify observers before destruction or using weak references.
Making sure subject state is self-consistent before notification — If a subject notifies observers in the middle of a state change, observers may see inconsistent state. Template Method can help ensure consistency is restored before notification.
The Implementation section provides guidance, not requirements. Different situations call for different choices. A pattern implemented in a high-performance system may differ from one in a simple application. Read implementation advice critically and adapt it to your context.
Language Evolution Changes Implementation
The GoF book's implementation advice was written for C++ (1994) and Smalltalk. Modern languages offer features that simplify many patterns:
When reading implementation sections, translate the advice to your language's idioms. The core insights remain valid; only the mechanics change.
Sample Code: Patterns Made Concrete
The Sample Code section provides code fragments that illustrate how to implement the pattern. In the GoF book, examples use C++ and Smalltalk. The code demonstrates the pattern's key aspects—not a complete application, but enough to see how the pattern translates to code.
Sample code serves several purposes:
When reading sample code, focus on understanding what it demonstrates rather than memorizing it. The specific code isn't important; the pattern it illustrates is.
Known Uses: Patterns in the Wild
The Known Uses section provides examples of the pattern in real systems. This grounds the pattern in reality—you're not learning a theoretical construct but a solution that has proven effective in production.
Example: Observer Known Uses (from GoF)
Known uses provide validation and context. When you see that major, successful systems use a pattern, you gain confidence in its applicability. You can also study these systems for deeper understanding of how the pattern works in practice.
As you learn patterns, note the systems where you encounter them. Your framework's event system (Observer), your ORM's builder API (Builder), your UI library's components (Composite)—building your own mental library of known uses deepens your pattern understanding and helps you recognize opportunities to apply patterns.
The Three-Uses Rule
The GoF authors had an explicit criterion: a pattern was only included if it appeared in at least three independent systems. This "rule of three" ensures that patterns represent truly reusable solutions, not just one-off designs that happened to work once.
When you see a pattern documented, you can trust that it has been validated across multiple contexts. When you consider documenting your own patterns, apply the same rigor: has this solution proven itself in at least three distinct applications?
Patterns Don't Exist in Isolation
The Related Patterns section describes relationships between the documented pattern and others—patterns that are often used together, patterns that are alternatives, and patterns that address similar problems with different trade-offs.
Relationships fall into several categories:
Complementary patterns — Often used together:
Alternative patterns — Solve similar problems differently:
Enabling patterns — One pattern makes another possible:
Contrasting patterns — Highlight differences through comparison:
| Pattern | Related Patterns | Relationship Type |
|---|---|---|
| Observer | Mediator, Singleton | Mediator centralizes Observer; Factory creates Observers |
| Strategy | Flyweight, State | Flyweight shares Strategies; State similar in structure |
| Decorator | Composite, Strategy | Both add behavior; Composite structures containers |
| Abstract Factory | Prototype, Singleton | Alternative implementations; Singleton factory instances |
| Composite | Iterator, Visitor, Flyweight | Traversal and sharing with composites |
| Command | Memento, Prototype | Undo support; Copying commands |
Using Related Patterns for Discovery
When a pattern doesn't quite fit your problem, the Related Patterns section points you toward alternatives. If Decorator seems close but not right, checking its related patterns reveals Strategy—which might be what you actually need.
As you learn more patterns, the web of relationships becomes a navigation tool. You don't memorize every pattern; you learn enough to navigate the catalog effectively.
Christopher Alexander's original vision was a 'pattern language'—interconnected patterns that work together to solve complex problems. The Related Patterns section captures this interconnection. As you gain experience, you learn not just individual patterns but how they combine into solutions for real-world systems.
Strategies for Different Needs
How you read a pattern depends on your purpose. Here are reading strategies for different situations:
When learning a pattern for the first time:
When evaluating whether to use a pattern:
When implementing a pattern you've chosen:
You don't need to memorize every pattern detail. Instead, aim to internalize the core concept of each pattern so you can recognize when it applies. Details can be looked up when needed. What you want in your mental toolkit is: 'There's a pattern for that problem—I know where to find it.'
Let's consolidate what we've learned about the pattern documentation format:
What's Next
Now that you understand how patterns are documented, we'll explore the evolution of patterns beyond the original GoF catalog. You'll learn how the patterns movement expanded, what new patterns emerged, how patterns adapted to new paradigms, and the current state of pattern thinking in modern software development.
You now understand the anatomy of pattern documentation. You can navigate pattern literature efficiently, extract the information you need, and evaluate patterns systematically. This skill serves you whether you're reading the original GoF book, exploring domain-specific pattern catalogs, or documenting patterns you discover in your own work.