# Design patterns

The 22 classic object-oriented design patterns plus original categories - resilience for calls that can fail, hang or come back wrong, data for keeping shared state honest across caches, messages and services, and architecture for system boundaries - grouped by intent. Read "Do not use it when" first.

## Creational Patterns

Patterns that control how objects get built, so callers depend on what they need rather than on which concrete class supplies it.

- [Factory Method](https://aipatterns.dev/design-patterns/factory-method.md): Let a subclass or a supplied function decide which concrete object to create, so shared workflow code depends only on an interface.
- [Abstract Factory](https://aipatterns.dev/design-patterns/abstract-factory.md): Create families of related objects through one interface so client code always gets a matching set and never names the concrete classes.
- [Builder](https://aipatterns.dev/design-patterns/builder.md): Assemble a complex object through named, step-by-step calls and validate it once in build(), instead of a constructor with many parameters.
- [Prototype](https://aipatterns.dev/design-patterns/prototype.md): Create new objects by copying a configured existing instance, so callers get a ready-made variant without knowing its class or setup.
- [Singleton](https://aipatterns.dev/design-patterns/singleton.md): Guarantee one instance of a class per process with a global access point. Usually better replaced by one instance created at startup and injected.

## Structural Patterns

Patterns that combine objects and classes into larger structures while keeping each part replaceable and its interface small.

- [Adapter](https://aipatterns.dev/design-patterns/adapter.md): Wrap an incompatible class in an object that exposes the interface your code expects, so you can use it without changing either side.
- [Bridge](https://aipatterns.dev/design-patterns/bridge.md): Split a class that varies along two dimensions into two hierarchies joined by composition, so each side grows without multiplying subclasses.
- [Composite](https://aipatterns.dev/design-patterns/composite.md): Treat single objects and nested groups of them through one interface, so code can walk a tree of any depth without checking node types.
- [Decorator](https://aipatterns.dev/design-patterns/decorator.md): Wrap an object in another object with the same interface that adds behavior before or after delegating, so features stack without subclassing.
- [Facade](https://aipatterns.dev/design-patterns/facade.md): Give a complex subsystem one small entry point for a common task, so callers stop orchestrating its classes and calling them in the right order.
- [Flyweight](https://aipatterns.dev/design-patterns/flyweight.md): Share one immutable object for state that many objects have in common, and pass the per-object rest in, to cut memory when instances number in the millions.
- [Proxy](https://aipatterns.dev/design-patterns/proxy.md): Put a stand-in with the same interface in front of an object to control access to it: create it lazily, check permissions, or reach it remotely.

## Behavioral Patterns

Patterns that assign responsibilities and route requests between objects, so behavior can change without rewriting the code that triggers it.

- [Chain of Responsibility](https://aipatterns.dev/design-patterns/chain-of-responsibility.md): Pass a request along a chain of handlers until one decides it, so the sender never knows which handler acts or how many exist.
- [Command](https://aipatterns.dev/design-patterns/command.md): Wrap an action and its arguments in an object so you can queue, log, retry or undo it separately from the code that triggers it.
- [Iterator](https://aipatterns.dev/design-patterns/iterator.md): Walk the elements of a collection one at a time through a standard interface, without exposing how the collection stores or fetches them.
- [Mediator](https://aipatterns.dev/design-patterns/mediator.md): Route interactions between a group of components through one coordinator so they stop referencing each other and the rules live in one place.
- [Memento](https://aipatterns.dev/design-patterns/memento.md): Capture an object's internal state in an opaque snapshot so it can be restored later without exposing that state to the code holding the snapshot.
- [Observer](https://aipatterns.dev/design-patterns/observer.md): Let an object announce its changes to a list of subscribers it does not know, so new reactions plug in without editing the source of the change.
- [State](https://aipatterns.dev/design-patterns/state.md): Move each mode of an object into its own class so behavior and transitions change with the mode instead of branching on a status field.
- [Strategy](https://aipatterns.dev/design-patterns/strategy.md): Put each interchangeable algorithm behind one interface so the caller picks a behavior at runtime without branching on it.
- [Template Method](https://aipatterns.dev/design-patterns/template-method.md): Fix an algorithm's sequence of steps in a base class and let subclasses fill in or override individual steps without changing the order.
- [Visitor](https://aipatterns.dev/design-patterns/visitor.md): Add new operations over a fixed set of node types without editing those types, by routing each node to a type-specific method on a visitor object.

## Resilience Patterns

Patterns for calls that can fail, hang or come back wrong: bound the wait, count the failures, space the repeats, and continue with a lesser answer.

- [Timeout](https://aipatterns.dev/design-patterns/timeout.md): Give every remote call a deadline shorter than the caller's own budget, cancel the work when it expires, and surface the timeout as a distinct error.
- [Circuit Breaker](https://aipatterns.dev/design-patterns/circuit-breaker.md): Count consecutive failures to a dependency, refuse calls while it looks broken, and let one probe test recovery - so a dead service cannot eat its callers.
- [Retry](https://aipatterns.dev/design-patterns/retry.md): Re-attempt only retryable, repeatable operations a bounded number of times, honour Retry-After, check cancellation between attempts, and surface the last error.
- [Exponential Backoff](https://aipatterns.dev/design-patterns/exponential-backoff.md): Space repeat attempts at base times two raised to the attempt, capped, with random jitter - so retries spread out instead of arriving in a synchronized herd.
- [Fallback](https://aipatterns.dev/design-patterns/fallback.md): Return a pre-decided lesser answer when a dependency cannot - stale cache, static default, partial result - so the journey continues, marked as degraded.
- [Rate Limiting](https://aipatterns.dev/design-patterns/rate-limiting.md): Give each client a refillable budget of calls - take a token to proceed, refuse with 429 and a Retry-After when the bucket is empty - so one client's burst cannot spend everyone's capacity.

## Data Patterns

Patterns for keeping application data honest at speed and across services: copies that exist only to be lost, multi-step transactions with explicit undos, and messages that cannot be lost or doubled.

- [Cache-Aside](https://aipatterns.dev/design-patterns/cache-aside.md): Read through a cache: on a miss, load from the store and fill it; on a write, save to the store and evict the entry - so reads speed up while the store stays the only source of truth.
- [Transactional Outbox](https://aipatterns.dev/design-patterns/transactional-outbox.md): Write the outgoing message in the same transaction as the business change; a relay publishes and marks it sent - the commit and the message become one fact, not two hopes.
- [Saga](https://aipatterns.dev/design-patterns/saga.md): Run a multi-step transaction as local steps, each with a compensation; on failure, compensate the completed steps in reverse - consistency by explicit undo, not locks.
- [Idempotent Consumer](https://aipatterns.dev/design-patterns/idempotent-consumer.md): Record the ids of processed messages and skip ids already seen, so a redelivered webhook or queue event processes once no matter how many times it arrives.
- [CQRS](https://aipatterns.dev/design-patterns/cqrs.md): Split the command model from per-view query models, joined by projections - each side shaped for its job, at the price of two models and eventual consistency.

## Architecture Patterns

Patterns for system boundaries and change over time: replace without stopping, and give each client a backend shaped for it - decisions measured in routes and releases, not classes.

- [Strangler Fig](https://aipatterns.dev/design-patterns/strangler-fig.md): Put an interception layer in front of a legacy system and move routes to the replacement one at a time, until the old system has nothing left to serve and can be removed.
- [Backends for Frontends](https://aipatterns.dev/design-patterns/backends-for-frontends.md): Give each frontend its own backend that aggregates and shapes the services it needs - so the web app, the mobile app, and any other client stop negotiating one API into serving them all.
