Design Patterns Directory
Explore proven design patterns for software architecture and code migration. Learn when to use each pattern and see related implementations.
Strangler Fig Pattern
Incrementally migrate a legacy system by gradually replacing pieces of functionality with new applications
Anti-Corruption Layer
Create a translation layer between new and legacy systems to prevent legacy concepts from leaking into new code
Blue-Green Deployment
Run two identical production environments, switching traffic between them for zero-downtime deployments
Canary Deployment
Gradually roll out changes to a small subset of users before rolling out to the entire infrastructure
Database per Service
Each microservice owns and manages its own database, enabling loose coupling and independent deployability
Saga Pattern
Manage data consistency across microservices using a sequence of local transactions with compensating actions
Event Sourcing
Store state changes as a sequence of events rather than just the current state
Backend for Frontend (BFF)
Create separate backend services tailored to each frontend's needs
Sidecar Pattern
Deploy auxiliary components alongside primary services for cross-cutting concerns
Feature Flags
Toggle functionality on or off without deploying new code
Factory Method
Defines an interface for creating an object but lets subclasses decide which concrete class to instantiate, deferring instantiation to subclasses.
Abstract Factory
Provides an interface for creating families of related objects without specifying their concrete classes, ensuring products from one family are used together.
Builder
Separates the construction of a complex object from its representation so the same construction process can create different representations step by step.
Prototype
Creates new objects by cloning an existing instance (the prototype) rather than instantiating a class, useful when construction is costly or types are decided at runtime.
Singleton
Ensures a class has only one instance and provides a global point of access to it, used for shared resources like configuration, logging, or connection pools.
Object Pool
Reuses a set of pre-initialized, expensive-to-create objects from a managed pool instead of creating and destroying them on demand, improving performance.
Dependency Injection
Supplies an object's dependencies from the outside rather than having it construct them, inverting control to improve testability, flexibility, and decoupling.
Lazy Initialization
Defers the creation or computation of an object until the first time it is actually needed, avoiding upfront cost for resources that may never be used.
Multiton
Generalizes Singleton to manage a fixed, keyed set of named instances, ensuring exactly one instance exists per key through a registry.
Registry
Provides a well-known central object where shared instances or services can be registered and looked up by key, giving a single point of access without scattered globals.
Adapter
Converts the interface of a class into another interface clients expect, letting classes that could not otherwise collaborate work together.
Bridge
Decouples an abstraction from its implementation so the two can vary independently, avoiding a combinatorial explosion of subclasses.
Composite
Composes objects into tree structures to represent part-whole hierarchies, letting clients treat individual objects and compositions uniformly.
Decorator
Attaches additional responsibilities to an object dynamically by wrapping it, providing a flexible alternative to subclassing for extending behavior.
Flyweight
Minimizes memory use by sharing as much data as possible between many similar objects, separating intrinsic shared state from extrinsic context-specific state.
Proxy
Provides a surrogate or placeholder for another object to control access to it, enabling lazy loading, access control, caching, or remote access.
Module
Encapsulates related code into a single self-contained unit with a controlled public interface and hidden private state, organizing code and avoiding global namespace pollution.
Marker Interface
Uses an empty interface to tag a class with metadata so other code can detect the capability at runtime via type checks, without adding any methods.
Mixin
Composes reusable units of behavior into a class without inheritance, letting unrelated classes share functionality by mixing in shared method sets.
Extension Object
Lets you add new interfaces and behavior to a class over time without changing it, by attaching extension objects that clients query for at runtime.
Private Class Data
Restricts accessor-write access to class attributes by isolating data in a separate object exposed read-only after construction, enforcing immutability and encapsulation.
Front Controller
Channels all incoming requests through a single handler that centralizes cross-cutting concerns like routing, authentication, and logging before dispatching to handlers.
Strategy
Defines a family of interchangeable algorithms behind a common interface so the algorithm can vary independently from the clients that use it.
Observer
Establishes a one-to-many dependency so that when one object changes state, all its dependents are notified and updated automatically.
Command
Encapsulates a request as an object, letting you parameterize, queue, log, and undo operations independently of who invokes them.
Iterator
Provides a uniform way to traverse the elements of a collection sequentially without exposing its underlying representation.
Mediator
Centralizes complex communication between objects in a mediator so components refer to it instead of to each other, reducing coupling.
Memento
Captures and externalizes an object's internal state so it can be restored later without violating encapsulation.
State
Lets an object alter its behavior when its internal state changes, appearing to change class by delegating to state-specific objects.
Template Method
Defines the skeleton of an algorithm in a base method, deferring specific steps to subclasses so they can vary parts without changing the structure.
Visitor
Separates an algorithm from the object structure it operates on, letting you add new operations over a class hierarchy without modifying it.
Chain of Responsibility
Passes a request along a chain of handlers, each deciding to process it or forward it, decoupling sender from the specific receiver.
Interpreter
Defines a grammar for a simple language and an interpreter that evaluates sentences in that language using a class per grammar rule.
Null Object
Provides a do-nothing object with neutral behavior in place of null, eliminating null checks and special-case handling.
Specification
Encapsulates a business rule as a reusable, combinable predicate object that tells whether a candidate satisfies the rule.
Publish-Subscribe
Decouples senders from receivers by routing messages through a broker or channel so publishers and subscribers never reference each other.
Servant
Defines shared behavior for a group of classes in a separate servant object that operates on them, instead of duplicating the behavior in each class.
Blackboard
Coordinates independent specialized components that incrementally build a shared solution on a common data store for ill-defined problems.
Repository
Mediates between the domain and data mapping layers via a collection-like interface for accessing domain objects, hiding persistence details.
Unit of Work
Tracks objects affected by a business transaction and coordinates writing out changes and resolving concurrency as a single commit.
Data Mapper
Moves data between objects and a database while keeping them independent, so domain objects carry no persistence knowledge.
Active Record
Wraps a database row in an object that carries both the data and the methods to load, save, and delete itself.
Value Object
Models a concept defined by its attributes rather than identity, making it immutable and compared by value to keep the domain expressive and safe.
Domain Event
Captures something significant that happened in the domain as an explicit object, decoupling the trigger from the reactions to it.
API Gateway
A single entry point that routes, aggregates, and secures client requests across many backend microservices.
Service Registry
A database of available service instances and their network locations, kept current as instances start, stop, and fail.
Service Discovery
A mechanism for clients to find the current network location of a service without hard-coding addresses.
Ambassador
An out-of-process helper that proxies network calls on behalf of an application, handling connectivity concerns transparently.
Adapter Microservice
A microservice that translates between an application and an external system with an incompatible interface or protocol.
Service Mesh
A dedicated infrastructure layer that manages service-to-service communication via co-located proxies and a central control plane.
API Composition
Implements a query that spans multiple services by invoking each owner service and joining the results in memory.
CQRS (Command Query Responsibility Segregation)
Separates the model that writes data (commands) from the model that reads it (queries) so each can be optimized independently.
Transactional Outbox
Reliably publishes messages by writing them to an outbox table in the same local transaction as the business data change.
Change Data Capture (CDC)
Captures row-level changes from a database's transaction log and streams them as events to downstream consumers.
Aggregator
A component that invokes multiple services and combines their responses into a single consolidated result for the caller.
Gateway Aggregation
Uses a gateway to combine multiple backend requests into one, so clients make a single call instead of many.
Gateway Offloading
Moves shared cross-cutting functionality such as TLS, auth, and rate limiting out of services and into a gateway.
Gateway Routing
Routes client requests to the correct backend service through a single endpoint using request attributes such as path or host.
Leader Election
Designates a single instance among many to coordinate work, with automatic failover if the leader becomes unavailable.
Distributed Lock
Coordinates exclusive access to a shared resource across multiple processes or nodes that do not share memory.
Consistent Hashing
Distributes keys across nodes so that adding or removing a node remaps only a small fraction of keys.
Sharding
Horizontally partitions a data store into independent shards so capacity and load scale beyond a single node.
Scatter-Gather
Broadcasts a request to multiple recipients in parallel, then aggregates their replies into a single response.
Choreography
Coordinates a distributed workflow through services reacting to each other's events, with no central controller.
Orchestration
Coordinates a distributed workflow through a central orchestrator that explicitly invokes each service in sequence.
Externalized Configuration
Stores configuration outside the application artifact so the same build runs unchanged across environments.
Cache-Aside
Load data into a cache on demand from a data store to improve read performance and reduce load on the backing store.
Competing Consumers
Enable multiple concurrent consumers to process messages from the same queue to increase throughput and improve resilience.
Queue-Based Load Leveling
Use a queue between tasks and a service to smooth intermittent heavy loads and protect the service from being overwhelmed.
Throttling
Control the consumption of resources by an instance, tenant, or service so a system stays within capacity under load.
Claim Check
Store a large message payload externally and pass only a reference through the messaging system to avoid moving bulky data.
Valet Key
Issue a client a token granting scoped, time-limited direct access to a resource, offloading data transfer from the application.
Gatekeeper
Protect services by brokering all client requests through a dedicated host that validates and sanitizes them before forwarding.
Federated Identity
Delegate authentication to an external identity provider so applications trust tokens rather than managing credentials themselves.
Compensating Transaction
Undo the completed steps of a multi-step operation when one step fails, restoring consistency without distributed ACID transactions.
Geode
Deploy independent geographically distributed nodes that each serve any request, placing compute close to users worldwide.
Deployment Stamps
Deploy multiple independent copies of a full application stack to scale, isolate tenants, and contain failures.
Static Content Hosting
Serve static assets from storage or a CDN instead of application servers to cut load, latency, and cost.
External Configuration Store
Move configuration out of deployment packages into a central external store shared and updated across application instances.
Health Endpoint Monitoring
Expose health-check endpoints that monitoring tools and load balancers probe to verify an application is functioning correctly.
Index Table
Create secondary index tables over data stores queried by non-key fields to speed up lookups that would otherwise scan.
Materialized View
Precompute and store read-optimized views of data so expensive queries become fast lookups against ready-made results.
Pipes and Filters
Decompose complex processing into a sequence of independent components connected by channels so each step can scale and evolve.
Sequential Convoy
Process related messages in order while still processing unrelated messages in parallel, by grouping them into ordered sets.
Rate Limiting
Constrain the rate of operations against a service or resource to stay within quotas and avoid throttling or overload.
Retry
Automatically reattempt a failed operation that is likely transient, using backoff and limits to recover without user impact.
Message Channel
Connects two applications with a logical pipe so a sender can transmit data to a receiver without knowing the receiver's location or identity.
Point-to-Point Channel
Ensures exactly one receiver consumes each message on a channel, even when multiple consumers compete, so a message is processed once.
Publish-Subscribe Channel
Broadcasts each message to all interested subscribers so one event can notify many independent consumers without the publisher knowing them.
Message Router
Consumes a message and redirects it to a different channel based on conditions, decoupling producers from the decision of where messages should go.
Content-Based Router
Routes each message to a destination channel chosen by inspecting the message's content, so the payload itself determines where it is delivered.
Message Filter
Lets only messages meeting specified criteria pass through a channel and silently discards the rest, so consumers receive only relevant messages.
Splitter
Breaks a composite message into a series of individual messages so each element can be processed independently downstream.
Message Translator
Converts a message from one data format or schema to another so systems with incompatible representations can communicate.
Content Enricher
Augments a message with additional data from an external source when the original lacks information the receiver requires.
Normalizer
Translates messages arriving in many different formats into a single common format so downstream components handle one canonical representation.
Polling Consumer
A consumer that explicitly checks a channel for messages on its own schedule, controlling exactly when and how fast it receives them.
Event-Driven Consumer
A consumer that is invoked by the messaging system the moment a message arrives, reacting to messages instead of polling for them.
Idempotent Receiver
Makes a consumer safely handle duplicate messages so that processing the same message more than once has the same effect as processing it once.
Dead Letter Channel
Routes messages that cannot be delivered or processed to a dedicated channel for inspection and recovery instead of discarding or blocking them.
Guaranteed Delivery
Persists messages so they are not lost if the sender, broker, or receiver fails, ensuring each message is eventually delivered despite outages.
Request-Reply
Lets a requestor send a message and receive a corresponding response over messaging, combining two one-way channels into a logical two-way exchange.
Correlation Identifier
Tags messages with a unique id that links related messages together, so a reply can be matched to its request and parts to their whole.
Wire Tap
Copies messages flowing through a channel to a secondary channel for inspection, logging, or analysis without disturbing the primary flow.
Routing Slip
Attaches a sequence of processing steps to a message so it routes itself through a series of components determined per message at runtime.
Process Manager
A central component that maintains the state of a multi-step message flow and decides the next step, coordinating complex or branching workflows.
Read-Through Cache
A caching strategy where the cache itself loads missing data from the backing store on a miss, so application code reads only from the cache.
Write-Through Cache
A caching strategy where every write goes to the cache and the backing store synchronously, keeping the two consistent at the cost of write latency.
Write-Behind Cache
A caching strategy where writes update the cache immediately and are flushed to the backing store asynchronously, maximizing write throughput at the cost of durability.
Refresh-Ahead Cache
A caching strategy that proactively reloads hot entries before they expire, so reads of popular keys never pay miss latency.
Materialized View
A precomputed, stored result set that trades storage and refresh cost for fast reads of expensive queries, aggregations, or denormalized projections.
Polyglot Persistence
An architecture that uses multiple, purpose-fit data stores within one system, matching each store's strengths to each data access pattern.
Command Query Responsibility Segregation (CQRS)
Separates the write model that handles commands from the read model that serves queries, letting each be optimized, scaled, and evolved independently.
Event-Driven Architecture
An architectural style where components communicate by producing and reacting to events, enabling loose coupling, asynchronous flow, and independent scaling.
Lambda Architecture
A big-data design that runs a batch layer for accurate historical views and a speed layer for low-latency recent data, merging both at query time.
Kappa Architecture
A streaming-first data design that uses a single processing path over an immutable log, reprocessing history by replay instead of a separate batch layer.
Medallion Architecture
A lakehouse data-organization pattern that refines data through bronze (raw), silver (cleaned), and gold (curated) layers for progressive quality and reuse.
Data Lakehouse
A data architecture that adds warehouse-style ACID tables, schema, and governance directly on low-cost data-lake storage, unifying analytics and ML on one platform.
Star Schema
A dimensional data-modeling pattern with a central fact table linked to denormalized dimension tables, optimized for fast, intuitive analytical queries.
Slowly Changing Dimension (SCD)
Techniques for handling changes to dimension attributes over time in a data warehouse, ranging from overwriting to preserving full historical versions.
Idempotent Writer
A pattern that makes repeated writes safe by ensuring duplicate operations produce the same result, essential for at-least-once delivery and retries.
Producer-Consumer
A concurrency pattern where producers place work on a shared bounded queue and consumers process it independently, decoupling rates and smoothing load.
Thread Pool
A concurrency pattern that reuses a fixed set of worker threads to execute many tasks, avoiding per-task thread creation cost and bounding concurrency.
Actor Model
A concurrency model where independent actors encapsulate state and communicate only by asynchronous messages, avoiding shared memory and locks.
Reactor
An event-handling pattern that demultiplexes I/O events on one or few threads and dispatches them synchronously to registered handlers, enabling scalable non-blocking servers.
Optimistic Concurrency Control
A concurrency strategy that lets transactions proceed without locking and validates at commit, retrying on conflict, assuming conflicts are rare.
Pessimistic Locking
A concurrency strategy that acquires locks on data before use to prevent concurrent modification, ensuring correctness under high contention at the cost of throughput.
Two-Phase Commit (2PC)
A distributed-transaction protocol that coordinates multiple participants to commit or abort atomically through a prepare phase and a commit phase.
Retry with Backoff
Automatically re-attempts a failed operation after progressively longer waits, smoothing over transient faults without overwhelming a struggling dependency.
Exponential Backoff with Jitter
Adds randomness to exponentially growing retry delays so that many clients do not retry in lockstep and overwhelm a recovering service.
Timeout
Bounds how long a caller waits for an operation, freeing resources and surfacing failures fast instead of blocking indefinitely on a slow or hung dependency.
Bulkhead
Isolates resources into independent pools so a failure or overload in one part of a system cannot consume capacity needed by the rest.
Rate Limiter
Caps how many requests a client or system may make in a time window, protecting services from overload, abuse, and runaway cost.
Load Shedding
Deliberately rejects or drops lower-priority work when a system nears capacity, preserving stability and protecting high-priority requests under overload.
Fallback
Provides an alternative response or behavior when a primary operation fails, keeping the system useful instead of returning an error to the user.
Graceful Degradation
Keeps core functionality working by selectively disabling or simplifying non-essential features when parts of a system fail or are overloaded.
Fail Fast
Detects invalid state or unavailable dependencies as early as possible and reports the error immediately, rather than continuing into deeper, costlier failure.
Fail Safe
Designs a system so that when a component fails it falls into a safe, known default state rather than an unsafe or undefined one.
Heartbeat
Has a component emit periodic signals so observers can detect when it has failed or become unreachable within a bounded time.
Health Check
Exposes endpoints that report whether a service is alive and ready to serve, enabling orchestrators and load balancers to route traffic only to healthy instances.
Watchdog
An independent supervisor that monitors a system or process and takes corrective action — restart, alert, or failover — when it stops responding.
Backpressure
Lets a slow consumer signal upstream producers to slow down, preventing unbounded queues and memory exhaustion when demand exceeds processing capacity.
Idempotency Key
Attaches a unique key to a request so the server can detect and de-duplicate retries, making non-idempotent operations safe to repeat.
Dead-Letter Queue
Routes messages that cannot be processed after repeated attempts to a separate queue for inspection and recovery, keeping the main pipeline flowing.
Poison Message Handling
Detects and quarantines messages that repeatedly crash or block a consumer, preventing one bad message from stalling an entire queue.
Hedged Requests
Sends a duplicate request to another replica after a delay, taking whichever response returns first to cut tail latency from slow servers.
Request Coalescing
Merges multiple concurrent identical requests into a single backend call and shares the result, preventing duplicate work and cache-stampede overload.
Distributed Tracing
Tracks a single request as it flows across many services by propagating context, producing an end-to-end timeline that reveals latency and failure sources.
Correlation ID
Assigns a unique identifier to a request and propagates it through every service and log, so related events across a distributed system can be tied together.
Container/Presentational Pattern
Separates components that fetch and manage data (containers) from components that only render UI from props (presentational), improving reuse and testability.
Higher-Order Component (HOC)
A function that takes a component and returns a new component with added behavior, enabling cross-cutting concerns to be shared without inheritance.
Render Props
A component shares logic by accepting a function prop that it calls with internal state, letting the caller control rendering while reusing behavior.
Custom Hooks
Extracts reusable stateful logic from React function components into named hook functions, sharing behavior without wrapper components or prop drilling.
Compound Components
A set of components that work together and share implicit state through context, giving consumers a flexible, declarative API for a composite widget.
Provider Pattern
Distributes shared state or services to a component subtree through context, avoiding prop drilling and centralizing access to cross-cutting data.
Model-View-Controller (MVC)
Separates an application into a model (data and rules), a view (presentation), and a controller (input handling), decoupling concerns for maintainability.
Model-View-ViewModel (MVVM)
Separates UI from logic via a view-model that exposes bindable state and commands, with two-way data binding keeping the view and view-model in sync.
Micro Frontend
Decomposes a web frontend into independently developed and deployed pieces owned by separate teams, then composes them into one application at runtime or build time.
Island Architecture
Renders a page as mostly static HTML with isolated interactive 'islands' that hydrate independently, minimizing JavaScript shipped to the browser.
Pagination
Splits a large result set into smaller pages so APIs and UIs can return and traverse data incrementally instead of loading everything at once.
HATEOAS
Hypermedia as the Engine of Application State: REST responses include links describing available actions, letting clients navigate the API by following links.
Idempotency Key
A client-supplied unique key lets a server detect and dedupe retried requests, so repeated submissions produce the same result exactly once.
API Versioning
Strategies for evolving an API without breaking existing clients, by exposing multiple versions through URLs, headers, or media types.
Webhook
A server pushes event notifications to a client-registered HTTP endpoint as events occur, replacing inefficient polling with real-time callbacks.
Defense in Depth
Layers multiple independent security controls so that if one fails, others still protect the system, avoiding reliance on any single defense.
Principle of Least Privilege
Grants every user, process, and service only the minimum permissions needed for its task, limiting the blast radius of compromise or error.
Token Bucket (Rate Limiting)
A rate-limiting algorithm where requests consume tokens refilled at a steady rate, allowing controlled bursts while capping the long-run request rate.
Secrets Rotation
Regularly replacing credentials, keys, and tokens, ideally automatically, to limit the time window in which a leaked or compromised secret is useful.
Secure by Default
Systems ship with the most secure configuration out of the box, requiring deliberate action to reduce security rather than to enable it.
Zero Trust Segmentation
Eliminates implicit network trust by authenticating and authorizing every request and dividing the network into fine-grained, individually protected segments.