bigonotes
CS ConceptsDesign Patterns

The Gang of Four (GoF)

Who the Gang of Four were, the 23 patterns they catalogued, and which ones you'll actually meet in modern code.

4 min readLast updated Design Patterns

In 1994 four authors published Design Patterns: Elements of Reusable Object-Oriented Software, which catalogued 23 patterns and gave the industry a shared design vocabulary. They're called the Gang of Four (GoF) simply because there were four of them. When people say "the classic design patterns", they usually mean this list.

The authors#

The four authors came from both industry and academia.

Author Background
Erich Gamma Swiss computer scientist; later co-created JUnit, led development tools at Eclipse, and works at Microsoft on VS Code
Richard Helm Worked at IBM Research; brought an industry perspective
Ralph Johnson Professor at the University of Illinois; the academic of the group
John Vlissides Worked at IBM Research and wrote widely on applying patterns well; died in 2005

They kept seeing the same problems and the same solutions across object-oriented systems, without shared names for them. So they catalogued them. The book was published by Addison-Wesley in October 1994.

What made the book influential#

Three choices made the book last.

  1. They discovered rather than invented. The patterns already existed in real code. GoF named and documented them, like biologists cataloguing species.
  2. They used a consistent template. Name and classification, intent, also known as, motivation, applicability, structure, participants, collaborations, consequences, implementation, sample code, known uses, related patterns. See How to Read a Design Pattern.
  3. They gave developers a language. Before: "I made a class with a private constructor that returns the same instance every time..." After: "I used a Singleton."

The 23 patterns#

The book groups its patterns into three families by the problem they solve.

Creational (5): how objects are created#

# Pattern Analogy Typical use
1 Singleton One president per country Shared config, connection pool
2 Factory Method Each pizza franchise makes its own style Creating platform-specific UI buttons
3 Abstract Factory A furniture line where every piece matches Cross-platform UI toolkits
4 Builder Assembling a sandwich step by step SQL query builders
5 Prototype Cloning Spawning many similar game enemies

Structural (7): how objects are connected#

# Pattern Analogy Typical use
6 Adapter Travel power-plug adapter Wrapping a third-party library
7 Bridge One remote, many devices Database drivers
8 Composite Folders inside folders File systems, UI trees
9 Decorator Coffee with add-ons Buffered I/O streams (io.BufferedReader)
10 Facade A restaurant waiter Simplifying a complex API
11 Flyweight Chess pieces sharing one icon Characters in a text editor
12 Proxy A credit card standing in for your bank account Lazy-loading images

Behavioral (11): how objects communicate#

# Pattern Analogy Typical use
13 Chain of Responsibility Approval chain in a company Middleware pipelines
14 Command A restaurant order ticket Undo/redo
15 Interpreter Translating a language Parsing small languages (regex, query DSLs)
16 Iterator Channel up/down on a TV remote for-each loops
17 Mediator Air traffic control Chat room server
18 Memento Game save points Undo snapshots
19 Observer Newsletter subscription Event listeners
20 State Vending machine modes TCP connection states
21 Strategy Choosing how to travel Pluggable sorting or pricing
22 Template Method A recipe with variations Framework hooks
23 Visitor A health inspector visiting each restaurant Compiler passes over an AST

Before and after GoF#

The book changed how developers talk about design.

Before (pre-1994) After
No common vocabulary; same solutions, different names A shared language for design
Knowledge was hard to share Faster communication and onboarding
Books explained how but rarely why Clear problem → solution → trade-off mapping

How the patterns fare today#

Used constantly: Iterator (built into most languages), Observer (every GUI and event system), Factory Method, Strategy, Singleton.

Most misused:

  • Singleton, which creates hidden global dependencies.
  • Factory, which over-engineers simple object creation.

Rarely hand-written: Interpreter (narrow use case), Visitor (powerful but complex), Flyweight (only worth it with very large numbers of objects).

Criticisms worth knowing:

  • Some patterns are workarounds for missing language features. First-class functions make Strategy and Command much lighter, for example.
  • Applied blindly, patterns lead to over-engineering.
  • The 1994 examples feel dated.

The core problems haven't changed, though, and the names are still the common vocabulary.

You already use GoF patterns#

Everyday Python code is full of GoF patterns, even if nobody names them:

import io
import logging
from abc import ABC, abstractmethod

names = ["bob", "Alice", "carol"]

# Iterator: every for loop walks an iterator
for name in names:
    print(name)

# Observer: a logger notifies every handler attached to it
logger = logging.getLogger("app")
logger.addHandler(logging.StreamHandler())
logger.warning("disk almost full")

# Decorator: BufferedReader wraps a raw stream and adds buffering
raw = io.BytesIO(b"hello")
reader = io.BufferedReader(raw)

# Strategy: the comparison (key function) is passed in
names.sort(key=str.lower)


# Template Method: the base class fixes the order of steps
class Game(ABC):
    @abstractmethod
    def initialize(self) -> None: ...

    @abstractmethod
    def start_play(self) -> None: ...

    @abstractmethod
    def end_play(self) -> None: ...

    def play(self) -> None:  # subclasses shouldn't override this
        self.initialize()
        self.start_play()
        self.end_play()

Key takeaways#

  • GoF = Gamma, Helm, Johnson, Vlissides; their 1994 book catalogued 23 patterns.
  • The split is 5 creational, 7 structural, 11 behavioral.
  • They documented existing practice and gave it names and a consistent template.
  • A small subset (Iterator, Observer, Factory, Strategy, Singleton, Decorator) covers most everyday code.
  • Modern languages make some patterns lighter, but the vocabulary still matters.

Found a mistake? Tell me on LinkedIn ↗

Further reading#