Design Patterns Quick Reference (GoF)
Creational Patterns
| Pattern | Intent | Problem Solved | When to Use | When to Avoid |
|---|---|---|---|---|
| Factory Method | Define object creation interface | Multiple ways to create objects | Subclasses determine which class to instantiate | Simple constructor is sufficient |
| Abstract Factory | Create families of related objects | Need consistent object families | Cross-platform UIs, themed components | Only one product family |
| Builder | Construct complex objects step-by-step | Objects with many optional parameters | Immutable objects, fluent APIs, complex construction | Simple objects with few properties |
| Prototype | Clone existing objects | Expensive object creation | Object templates, reducing initialization cost | Objects are cheap to create |
| Singleton | Single instance globally | Shared resource access | Config, logging (prefer DI instead) | Almost always (use DI) |
Structural Patterns
| Pattern | Intent | Problem Solved | When to Use | When to Avoid |
|---|---|---|---|---|
| Adapter | Make incompatible interfaces compatible | Legacy code integration, third-party library mismatch | Wrapping existing classes with incompatible interfaces | You control both interfaces (fix design) |
| Bridge | Separate abstraction from implementation | Cartesian product explosion (N × M classes) | Multiple dimensions of variation | Single dimension of variation |
| Composite | Treat individual and composite objects uniformly | Tree structures, hierarchies | File systems, UI components, organizational charts | Flat structures |
| Decorator | Add behavior dynamically without subclassing | Static inheritance limitations | Runtime behavior modification, multiple combinations | Behavior known at compile time |
| Facade | Simplify complex subsystem interfaces | Too many dependencies, complex APIs | Hide complexity, reduce coupling | Subsystem is already simple |
| Flyweight | Share common state to reduce memory | Memory constraints with many similar objects | Large number of fine-grained objects | Few objects or mostly unique state |
| Proxy | Control access to objects | Expensive object creation, access control | Lazy loading, caching, access control, logging | Direct access is simpler |
Behavioral Patterns
| Pattern | Intent | Problem Solved | When to Use | When to Avoid |
|---|---|---|---|---|
| Observer | Notify dependents of state changes | Maintaining consistency between objects | Event systems, data binding, pub/sub | Simple callbacks work |
| Strategy | Interchangeable algorithms | Eliminating algorithm conditionals | Runtime algorithm selection | Single algorithm |
| Command | Encapsulate requests as objects | Undo/redo, operation queuing | Macro recording, transaction systems | Simple method calls |
| State | Behavior changes with state | Complex state conditionals | State machines, workflow | Simple if/switch suffices |
| Chain of Responsibility | Pass request along handler chain | Decoupling sender from receiver | Middleware pipelines, request processing | Single handler |
| Template Method | Algorithm skeleton in base class | Code reuse with variation | Common workflow with varying steps | No variation needed |
| Mediator | Centralize object communications | Many-to-many complexity | Chat systems, CQRS (MediatR) | Simple relationships |
| Memento | Capture/restore state | Undo/redo while maintaining encapsulation | Snapshots, transaction rollback | Simple state storage |
| Visitor | Add operations to hierarchies | Adding operations without modification | Expression trees, AST processing | Pattern matching is simpler |
| Iterator | Sequential access to elements | Collection traversal | Custom iteration logic | foreach works |
| Interpreter | Define language grammar | Domain-specific languages | Simple DSLs | Complex grammars (use parser) |
Found this useful? Share it:
Share on LinkedIn