# 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.

- kind: guide
- category: design-patterns
- aliases: Design pattern, Pattern
- canonical: https://aipatterns.dev/guides/what-is-a-pattern
- inspired-by: https://refactoring.guru/design-patterns/what-is-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](https://aipatterns.dev/design-patterns/observer.md) 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](https://aipatterns.dev/design-patterns/strategy.md), [Adapter](https://aipatterns.dev/design-patterns/adapter.md) |
| 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](https://aipatterns.dev/guides/for-agents.md).

## Roles, not classes

A pattern describes *roles*. In [Strategy](https://aipatterns.dev/design-patterns/strategy.md), 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:

```ts
// 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); // 180
```

There 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](https://aipatterns.dev/guides/classification-of-patterns.md), or browse [creational](https://aipatterns.dev/design-patterns/creational.md), [structural](https://aipatterns.dev/design-patterns/structural.md) and [behavioral](https://aipatterns.dev/design-patterns/behavioral.md) directly.

## A worked recognition

You find this in a codebase:

```ts
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](https://aipatterns.dev/design-patterns/strategy.md). It also matches the [Switch Statements](https://aipatterns.dev/refactoring/smells/switch-statements.md) smell, and the refactoring path is [Replace Conditional with Polymorphism](https://aipatterns.dev/refactoring/techniques/replace-conditional-with-polymorphism.md).

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](https://aipatterns.dev/guides/choosing-a-pattern.md) before introducing one, and [Criticism of patterns](https://aipatterns.dev/guides/criticism-of-patterns.md) to know the failure modes.
