Library
Patterns
A growing set of design patterns with implementation notes, tradeoffs, and cross-stack integration guidance.
Abstract Factory
Provide an interface for creating families of related objects without specifying their concrete classes.
Problem: Client code needs to create families of related objects, but hardcoding concrete classes makes the code rigid and hard to swap.
Languages: typescript, java, python, react, angular, csharp, dotnet
Integration: Abstract Factory is especially useful when your app must produce matching sets of related objects for a theme, provider, platform, or pipeline.
Adapter
Allow incompatible interfaces to work together without changing the consuming code.
Problem: A client needs to talk to a legacy class or external service whose interface does not match the rest of the codebase.
Languages: typescript, java, python, go, csharp, dotnet, react, angular, react-native
Integration: Adapters are useful when exposing a stable boundary over a legacy API, vendor SDK, or payload format mismatch.
Bridge
Decouple abstractions from implementations so they can evolve independently.
Problem: When an abstraction is tightly coupled to its implementation, changing one side forces changes in the other and makes the system harder to evolve.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet, go
Integration: Bridge is useful when you want one stable abstraction while swapping implementations for providers, environments, or device targets.
Builder
Separate the construction of a complex object from its final representation.
Problem: Constructing complex objects directly can make required steps, optional values, and validation hard to manage.
Languages: typescript, python, java, react, angular, go, csharp, dotnet
Integration: Builder is most useful when construction must happen in controlled steps and the final object has many optional or ordered parts.
Chain of Responsibility
Pass requests along a chain of handlers until one of them handles the request or the request reaches the end of the chain.
Problem: A request must pass through multiple possible handlers, but the sender should not need to know which handler will process it.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Chain of Responsibility is useful for validation pipelines, support routing, approval flows, and any system where requests may be processed by different handlers in sequence.
Command
Encapsulate a request as an object so it can be invoked, queued, logged, or undone independently of the receiver that performs the work.
Problem: A system needs to trigger actions without tightly coupling the code that requests an operation to the code that performs it, and it may also need queuing, history, or undo support.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Commands work well for UI actions, background jobs, workflow steps, and undoable operations because invokers can trigger commands without depending on receiver details.
Composite
Compose objects into tree structures to represent part-whole hierarchies and let clients work with individual and composite objects through the same interface.
Problem: A system needs to treat individual objects and groups of objects uniformly, but the hierarchy becomes difficult to manage with separate code paths.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Composite is useful when a hierarchy of nested objects should expose a common interface, such as files and folders, menus and submenus, org charts, widget trees, or scene graphs.
Decorator
Wrap an object with other objects that implement the same contract so responsibilities can be layered dynamically.
Problem: A system needs to add optional behaviors to an object without creating many subclasses for every feature combination.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Decorators work well for cross-cutting concerns such as logging, retry, caching, compression, and telemetry because each layer keeps the same interface while adding one concern.
Facade
Provide a simplified high-level interface that coordinates a complex subsystem behind a smaller and easier-to-use API.
Problem: A client needs to perform a recurring workflow that spans several subsystem classes, but direct coordination makes the code noisy and tightly coupled.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Facades are useful when exposing a stable boundary over a multi-service or mixed-language backend, or when presenting a consistent UI entry point over multiple readiness checks.
Factory Method
Define a creation method behind a common interface so specialized creators can decide which concrete product to instantiate without changing the surrounding workflow.
Problem: A workflow needs to create one of several related concrete objects, but constructing them directly in client code spreads creation logic and tightly couples the caller to specific implementations.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Factory Method is useful when framework hooks, integrations, or environment-specific workflows need to create interchangeable implementations behind a stable contract.
Flyweight
Use sharing to support large numbers of fine-grained objects efficiently by separating shared intrinsic state from per-object extrinsic state.
Problem: A system creates a large number of similar objects, but storing all of their state separately uses too much memory.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Flyweight is useful when thousands or millions of similar objects need to be represented efficiently, such as trees, glyphs, tiles, or UI tokens.
Interpreter
Represent grammar rules as objects and interpret sentences by evaluating an abstract syntax tree or expression chain.
Problem: You need to define a small language or expression grammar and evaluate it consistently across the application.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Interpreter is useful for calculators, rule engines, simple DSLs, and command parsing systems where a structured grammar must be evaluated.
Iterator
Provide a way to access elements of an aggregate sequentially while hiding the underlying representation.
Problem: A collection needs to be traversed without exposing how it is stored internally.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Iterator is useful for pagination, custom collections, ordered traversal, and any case where clients should not know the internal data structure.
Mediator
Define an object that encapsulates communication between a set of objects, keeping them from referring to each other directly.
Problem: Multiple objects need to coordinate behavior, but direct references between them create tight coupling and complex dependencies.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Mediator is useful for chat systems, form coordination, workflow orchestration, and any domain where many components must collaborate without knowing about each other.
Memento
Capture and externalize an object's state so it can be restored to a previous point in time.
Problem: An object's internal state must be saved and restored later without exposing its implementation details.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Memento is useful for undo/redo, checkpoints, draft recovery, and any workflow where state history matters.
Observer
Define a subscription mechanism so multiple observers can react to subject events without the subject knowing concrete subscriber details.
Problem: A system needs to notify multiple dependent objects when state changes occur, but hardcoding those dependencies makes the design rigid and tightly coupled.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Observers work well inside a single application boundary for UI events, domain events, and in-process notifications where subscribers change dynamically.
Prototype
Specify the kinds of objects to create using a prototypical instance, and create new objects by cloning that prototype.
Problem: Creating new objects from scratch can be expensive or repetitive when the system needs many similar variants.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Prototype is useful when object creation is expensive, when many near-identical objects are needed, or when cloning preconfigured templates is simpler than rebuilding them.
Proxy
Provide a surrogate or placeholder for another object to control access to it.
Problem: A client needs to interact with an object indirectly because the real object may be expensive, sensitive, or remote.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Proxy is useful for lazy loading, access control, caching, logging, and remote service wrappers.
Singleton
Ensure a class has only one instance and provide a global access point to it.
Problem: A system needs exactly one shared instance of a class, and that instance must be globally accessible without allowing uncontrolled duplication.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Singleton is useful for centralized services like configuration, logging, caching, and shared application state.
State
Allow an object to alter its behavior when its internal state changes by delegating state-specific behavior to separate state objects.
Problem: An object behaves differently depending on its internal state, and conditional logic is becoming hard to manage.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: State is useful for workflows, media players, order lifecycles, and any domain where behavior changes as the object moves through a lifecycle.
Strategy
Encapsulate a family of algorithms or behaviors behind a common contract so they can be selected and swapped cleanly.
Problem: A system needs to switch between interchangeable behaviors without hardcoding branching logic everywhere.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Strategies can cross codebases through shared contracts, API selection rules, or runtime configuration.
Template Method
Define the skeleton of an algorithm in a base class and let subclasses override selected steps without changing the overall structure.
Problem: Several classes share the same algorithm structure, but some steps need to vary between implementations.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Template Method is useful when you have repeated workflows with a common sequence of steps, such as processing orders, generating reports, and importing data.
Visitor
Separate an algorithm from the object structure it operates on by moving behavior into visitor objects.
Problem: You need to perform operations across a set of different object types without stuffing all the logic into the objects themselves.
Languages: typescript, java, python, angular, react, react-native, csharp, dotnet
Integration: Visitor is useful for AST processing, reporting, cart calculations, and exporting object structures to alternate formats.