Design patterns Cheatsheet

# Design Patterns Cheat Sheet

A quick reference guide to the most common software design patterns.

## Creational Patterns
*Deal with object creation mechanisms*

### Singleton
**Purpose:** Ensure a class has only one instance and provide global access to it.

**When to use:**
– Need exactly one instance (database connection, logger, configuration)
– Global state management

**Key points:**
– Private constructor
– Static instance variable
– Static access method

**Example use cases:** Database connections, logging, caching, thread pools

### Factory Method
**Purpose:** Define an interface for creating objects, but let subclasses decide which class to instantiate.

**When to use:**
– Class can’t anticipate object types to create
– Want to delegate instantiation to subclasses
– Need to localize object creation logic

**Key points:**
– Defines interface for creating objects
– Subclasses override to specify concrete types
– Promotes loose coupling

**Example use cases:** UI frameworks (creating buttons/dialogs per OS), document generators, database connectors

### Abstract Factory
**Purpose:** Provide an interface for creating families of related objects without specifying concrete classes.

**When to use:**
– System needs to be independent of product creation
– Need to work with multiple families of related products
– Want to enforce product family constraints

**Key points:**
– Factory of factories
– Creates related object families
– Enforces consistency among products

**Example use cases:** UI themes (dark/light mode), cross-platform libraries, database drivers

### Builder
**Purpose:** Separate construction of complex objects from their representation, allowing same construction process to create different representations.

**When to use:**
– Object construction is complex with many parameters
– Want to create different representations of the same object
– Need step-by-step construction

**Key points:**
– Fluent interface (method chaining)
– Separates construction from representation
– Director optional for reusing construction sequences

**Example use cases:** Query builders, document generators, HTTP request builders, configuration objects

### Prototype
**Purpose:** Create new objects by copying existing objects (cloning).

**When to use:**
– Object creation is expensive
– Need to avoid subclassing
– Want to hide construction complexity

**Key points:**
– Cloning instead of instantiation
– Deep vs shallow copy considerations
– Prototype registry optional

**Example use cases:** Game object spawning, document templates, configuration presets

## Structural Patterns
*Deal with object composition and relationships*

### Adapter
**Purpose:** Convert interface of a class into another interface clients expect, allowing incompatible classes to work together.

**When to use:**
– Want to use existing class with incompatible interface
– Need to create reusable class cooperating with unrelated classes
– Legacy code integration

**Key points:**
– Wraps existing class
– Translates interface
– Two variants: class adapter (inheritance) and object adapter (composition)

**Example use cases:** Third-party library integration, legacy system interfaces, payment gateway wrappers

### Bridge
**Purpose:** Decouple abstraction from implementation so both can vary independently.

**When to use:**
– Want to avoid permanent binding between abstraction and implementation
– Both abstractions and implementations should be extensible
– Need to share implementation among multiple objects

**Key points:**
– Separates interface from implementation
– Composition over inheritance
– Two hierarchies: abstraction and implementation

**Example use cases:** Device drivers, rendering engines across platforms, remote controls for devices

### Composite
**Purpose:** Compose objects into tree structures to represent part-whole hierarchies, treating individual objects and compositions uniformly.

**When to use:**
– Need to represent hierarchies of objects
– Want clients to treat individual and composite objects uniformly
– Tree structures needed

**Key points:**
– Recursive composition
– Uniform treatment of leaves and composites
– Tree traversal

**Example use cases:** File systems, UI component hierarchies, organization charts, graphic drawing systems

### Decorator
**Purpose:** Attach additional responsibilities to objects dynamically, providing flexible alternative to subclassing.

**When to use:**
– Need to add functionality without modifying existing code
– Want to add/remove responsibilities dynamically
– Subclassing is impractical

**Key points:**
– Wraps original object
– Same interface as wrapped object
– Can stack multiple decorators
– Open/Closed Principle

**Example use cases:** I/O streams, UI components with scrollbars/borders, middleware chains, caching layers

### Facade
**Purpose:** Provide unified interface to a set of interfaces in a subsystem, simplifying complex systems.

**When to use:**
– Want to provide simple interface to complex subsystem
– Need to layer subsystems
– Reduce coupling between client and subsystem

**Key points:**
– Simplified interface
– Doesn’t prevent access to subsystem
– Can provide multiple facades

**Example use cases:** Library wrappers, API simplification, complex initialization sequences

### Flyweight
**Purpose:** Use sharing to support large numbers of fine-grained objects efficiently.

**When to use:**
– Application uses many similar objects
– Storage costs are high
– Object state can be made extrinsic

**Key points:**
– Shares intrinsic state
– Extrinsic state passed as parameters
– Object pooling
– Memory optimization

**Example use cases:** Text editors (character objects), game engines (particle systems), caching

### Proxy
**Purpose:** Provide surrogate or placeholder for another object to control access to it.

**When to use:**
– Need lazy initialization (virtual proxy)
– Need access control (protection proxy)
– Need remote object representation (remote proxy)
– Need additional behavior on access

**Key points:**
– Same interface as real object
– Controls access
– Can add functionality

**Types:**
– Virtual Proxy (lazy loading)
– Protection Proxy (access control)
– Remote Proxy (remote object)
– Smart Reference (additional actions)

**Example use cases:** Lazy image loading, access control, logging, caching, remote services

## Behavioral Patterns
*Deal with object interaction and responsibility distribution*

### Chain of Responsibility
**Purpose:** Pass requests along chain of handlers, allowing multiple objects chance to handle request.

**When to use:**
– Multiple objects can handle request
– Handler not known in advance
– Want to issue request without specifying receiver
– Set of handlers determined dynamically

**Key points:**
– Decouples sender from receiver
– Dynamic chain configuration
– Request may go unhandled

**Example use cases:** Event handling, logging levels, middleware chains, approval workflows

### Command
**Purpose:** Encapsulate request as an object, allowing parameterization and queuing of requests.

**When to use:**
– Need to parameterize objects with operations
– Queue or log operations
– Support undo/redo
– Macro commands (composite commands)

**Key points:**
– Encapsulates action as object
– Supports undo/redo
– Can queue/schedule commands
– Decouples invoker from receiver

**Example use cases:** UI buttons/menus, transaction systems, task scheduling, macro recording, undo/redo

### Iterator
**Purpose:** Provide way to access elements of aggregate object sequentially without exposing underlying representation.

**When to use:**
– Need to traverse collection without exposing structure
– Support multiple traversals simultaneously
– Provide uniform interface for different collections

**Key points:**
– Separates traversal from collection
– Multiple iterators can exist
– Standard interface

**Example use cases:** Collection traversal, database cursors, file system navigation

### Mediator
**Purpose:** Define object that encapsulates how set of objects interact, promoting loose coupling.

**When to use:**
– Objects communicate in complex ways
– Want to reuse objects independently
– Many-to-many relationships need simplification

**Key points:**
– Centralized control
– Reduces coupling
– Easy to understand interactions

**Example use cases:** Chat rooms, air traffic control, UI dialog coordination, event systems

### Memento
**Purpose:** Capture and externalize object’s internal state for later restoration without violating encapsulation.

**When to use:**
– Need to save/restore object state
– Direct access to state violates encapsulation
– Undo mechanism needed

**Key points:**
– Preserves encapsulation
– Snapshot of state
– Caretaker manages mementos

**Example use cases:** Undo/redo, checkpoints, transaction rollback, editor history

### Observer
**Purpose:** Define one-to-many dependency where state change in one object notifies all dependents automatically.

**When to use:**
– Change in one object requires changing others
– Don’t know how many objects need notification
– Object should notify without knowing who they are

**Key points:**
– Subject maintains list of observers
– Automatic notification
– Loose coupling
– Can cause cascade updates

**Example use cases:** Event systems, MVC architecture, data binding, real-time dashboards, pub/sub systems

### State
**Purpose:** Allow object to alter behavior when internal state changes, appearing to change class.

**When to use:**
– Object behavior depends on state
– Complex conditionals depend on state
– State transitions are explicit

**Key points:**
– Encapsulates state-specific behavior
– State transitions explicit
– Eliminates large conditionals

**Example use cases:** TCP connections, document workflows, game character states, vending machines

### Strategy
**Purpose:** Define family of algorithms, encapsulate each, and make them interchangeable.

**When to use:**
– Many related classes differ only in behavior
– Need different variants of algorithm
– Algorithm uses data clients shouldn’t know about
– Class defines many behaviors as conditionals

**Key points:**
– Encapsulates algorithms
– Runtime algorithm selection
– Eliminates conditionals
– Open/Closed Principle

**Example use cases:** Sorting algorithms, payment methods, compression algorithms, validation strategies

### Template Method
**Purpose:** Define skeleton of algorithm in base class, letting subclasses override specific steps without changing structure.

**When to use:**
– Common algorithm structure with varying steps
– Want to control extension points
– Need to avoid code duplication

**Key points:**
– Abstract class defines template
– Subclasses override specific steps
– Hollywood Principle (“Don’t call us, we’ll call you”)
– Can define hooks

**Example use cases:** Frameworks, data processing pipelines, game loops, document generators

### Visitor
**Purpose:** Represent operation to be performed on elements of object structure, letting you define new operation without changing element classes.

**When to use:**
– Need to perform operations on diverse objects
– Many distinct operations needed
– Object structure rarely changes but operations often do
– Need to gather related operations

**Key points:**
– Double dispatch
– Separates algorithm from object structure
– Adding new operations easy
– Adding new elements hard

**Example use cases:** Compiler AST operations, reporting on object structures, exporting to different formats

## Quick Selection Guide

### Need to create objects?
– **One instance globally?** → Singleton
– **Family of related objects?** → Abstract Factory
– **Subclass decides type?** → Factory Method
– **Complex construction?** → Builder
– **Copy existing object?** → Prototype

### Need to structure objects?
– **Incompatible interfaces?** → Adapter
– **Separate abstraction/implementation?** → Bridge
– **Part-whole hierarchy?** → Composite
– **Add functionality dynamically?** → Decorator
– **Simplify complex system?** → Facade
– **Share objects efficiently?** → Flyweight
– **Control access?** → Proxy

### Need to manage behavior?
– **Chain of handlers?** → Chain of Responsibility
– **Encapsulate action?** → Command
– **Traverse collection?** → Iterator
– **Centralize communication?** → Mediator
– **Save/restore state?** → Memento
– **Notify dependents?** → Observer
– **Behavior depends on state?** → State
– **Interchangeable algorithms?** → Strategy
– **Algorithm template?** → Template Method
– **Operations on structure?** → Visitor

## Key Principles

**SOLID Principles:**
– **S**ingle Responsibility
– **O**pen/Closed (open for extension, closed for modification)
– **L**iskov Substitution
– **I**nterface Segregation
– **D**ependency Inversion

**Other Important Principles:**
– DRY (Don’t Repeat Yourself)
– KISS (Keep It Simple, Stupid)
– YAGNI (You Aren’t Gonna Need It)
– Composition over Inheritance
– Program to Interface, not Implementation
– Hollywood Principle (Don’t call us, we’ll call you)

## Common Combinations

– **MVC**: Observer + Strategy + Composite
– **Document Editor**: Command + Memento + Composite
– **Game Development**: State + Strategy + Observer + Object Pool (Flyweight variant)
– **Middleware Pipeline**: Chain of Responsibility + Decorator
– **Plugin Architecture**: Abstract Factory + Strategy + Observer

*Remember: Patterns are guidelines, not rules. Use them when they solve real problems, not just because they exist.*

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top