Guide
What Is a Design Pattern
A design pattern is a named, reusable solution shape for a recurring design problem. Learn what one contains and how it differs from an algorithm or library.
- Also known as
- Design pattern, Pattern
Definition
A design pattern is a description of how to arrange classes, objects or functions to solve a problem that keeps coming back in different programs. It is not code you copy. It is a shape you adapt.
A pattern names a recurring problem, the forces that make it hard, and a solution structure that balances those forces.
Think of a pattern as a blueprint for a kind of building, not the building itself. Two teams applying Observer will write different code, in different languages, with different names. A reader who knows the pattern still recognizes both.
Pattern vs algorithm vs library
| Thing | What it gives you | Example |
|---|---|---|
| Algorithm | Exact steps that produce a result | Binary search, Dijkstra |
| Library | Working code you call | lodash, java.util.concurrent |
| Pattern | A structure of roles and relationships | Strategy, Adapter |
| Idiom | A language-specific habit | Python context managers, Go defer |
An algorithm tells you what to compute. A pattern tells you who should know about whom. You can implement the same algorithm with or without a pattern, and the same pattern around many algorithms.
What a pattern description contains
Every pattern page on this site follows the same structure, because an agent should find the same facts in the same place:
- Intent: the problem and the solution in two or three sentences.
- Forces: the competing pressures. Without forces, a pattern reads like a rule; with them, you can tell when it does not apply.
- Therefore: the solution in one sentence.
- Structure: the participants (roles) and how they connect, as a class diagram.
- Use it when and Do not use it when: concrete triggers, and the simpler alternative for each misfit.
- Example: one realistic scenario in four languages.
- Trade-offs and Relations: what you pay, and which neighbors to compare against.
The "Do not use it when" section matters most. See Using this reference as an agent.
Roles, not classes
A pattern describes roles. In Strategy, the roles are context, strategy interface and concrete strategy. One class can play more than one role, and a role can be played by something that is not a class at all:
// The "strategy" role played by a plain function type.
type PriceRule = (subtotal: number) => number;
const tenPercentOff: PriceRule = (s) => s * 0.9;
const noDiscount: PriceRule = (s) => s;
function checkout(subtotal: number, rule: PriceRule): number {
return rule(subtotal);
}
checkout(200, tenPercentOff); // 180There is no interface keyword and no class here. The pattern is still present: a caller delegates a varying step to an interchangeable value. Recognizing patterns by role instead of by syntax keeps you from adding ceremony that the language already makes unnecessary.
Levels of scale
Patterns exist at several sizes:
- Idioms: tied to one language. Not covered here.
- Design patterns: a handful of collaborating objects. The 22 entries in this catalog.
- Architectural patterns: the shape of a whole system, such as layered architecture, ports and adapters, or event sourcing.
The classic catalog sorts design patterns into three groups by purpose. See Classification of patterns, or browse creational, structural and behavioral directly.
A worked recognition
You find this in a codebase:
class ReportExporter {
export(report: Report, format: "csv" | "pdf" | "xlsx"): Buffer {
if (format === "csv") { /* 40 lines */ }
else if (format === "pdf") { /* 60 lines */ }
else { /* 50 lines */ }
}
}The problem is recurring (pick one of several algorithms at runtime). The forces are present (new formats keep arriving, each branch is hard to test alone). That matches the intent of Strategy. It also matches the Switch Statements smell, and the refactoring path is Replace Conditional with Polymorphism.
If there were only two formats and no third in sight, the right call is to leave the if alone. A pattern is a response to forces, not a goal.
Key points for agents
- Match on the problem and forces, never on surface keywords in the request.
- A pattern is a vocabulary item. Naming it in a commit message or comment ("adapter for the legacy billing API") tells the next reader a lot in a few words.
- Prefer the smallest structure that plays the needed roles. Functions, closures and modules count.
- Read Choosing a pattern before introducing one, and Criticism of patterns to know the failure modes.
See also
- History of PatternsWhere design patterns came from, from Christopher Alexander's architecture books to the Gang of Four catalog, and what changed in how they are used today.
- Why Learn PatternsWhat knowing design patterns buys a developer or coding agent: shared vocabulary, faster code reading, better refactoring targets, and knowing when to stop.
- Classification of PatternsHow the 22 classic design patterns are grouped by purpose into creational, structural and behavioral, plus other useful ways to slice them.
- Choosing a PatternA decision guide that maps concrete code symptoms to the pattern that fixes them, and tells you when plain code beats any pattern.
Original writing and examples. Topic coverage follows Refactoring.Guru, which explains this topic with its own illustrations.