Design Patterns
Recurring solutions to common software design problems. Use as vocabulary, not as checklist.
Creational Patterns
| Pattern |
Purpose |
When to Use |
| Factory Method |
Delegate instantiation to subclasses |
Class can't anticipate subclass; delegate creation |
| Abstract Factory |
Families of related objects without concrete classes |
Multiple product families; enforce consistency |
| Builder |
Construct complex objects step by step |
Many optional parameters; immutable objects |
| Prototype |
Clone existing objects |
Creation expensive; similar objects with variations |
| Singleton |
Ensure single instance; global access |
Rarely — prefer dependency injection; testability issues |
Structural Patterns
| Pattern |
Purpose |
When to Use |
| Adapter |
Make incompatible interfaces work together |
Legacy code; third-party libs; interface mismatch |
| Bridge |
Decouple abstraction from implementation |
Both vary independently; avoid permanent binding |
| Composite |
Tree structures of objects (part-whole) |
Hierarchies; uniform treatment of leaf/composite |
| Decorator |
Add behavior dynamically |
Open/Closed; alternative to subclassing |
| Facade |
Simplified interface to complex subsystem |
Reduce coupling; provide simple entry point |
| Flyweight |
Share fine-grained objects efficiently |
Many similar objects; memory constrained |
| Proxy |
Placeholder controlling access |
Lazy loading; access control; logging; remote |
Behavioral Patterns
| Pattern |
Purpose |
When to Use |
| Chain of Responsibility |
Pass request along handler chain |
Multiple handlers; dynamic dispatch |
| Command |
Encapsulate request as object |
Undo/redo; queue requests; macro commands |
| Interpreter |
Define grammar + interpreter |
DSLs; rule engines; simple languages |
| Iterator |
Sequential access without exposing structure |
Aggregate objects; multiple traversals |
| Mediator |
Centralize communication between objects |
Reduce coupling; complex interactions |
| Memento |
Capture/restore object state |
Undo; snapshots; checkpoints |
| Observer |
Publish/subscribe notifications |
Event-driven; loose coupling |
| State |
Alter behavior when internal state changes |
Complex state-dependent behavior |
| Strategy |
Encapsulate interchangeable algorithms |
Algorithm varies; runtime selection |
| Template Method |
Define skeleton; defer steps to subclasses |
Common algorithm structure; variant steps |
| Visitor |
Add operations without modifying classes |
Stable object structure; varying operations |
Enterprise Patterns (Martin Fowler)
Domain Logic
| Pattern |
Description |
| Transaction Script |
Single procedure per use case; simple but doesn't scale |
| Domain Model |
Rich objects with behavior + data; complex domains |
| Table Module |
One class per DB table; business logic in class |
| Service Layer |
Defines application boundary; coordinates transactions |
Data Source
| Pattern |
Description |
| Active Record |
Domain object wraps DB row + access |
| Data Mapper |
Separates domain from DB; mapper in between |
| Repository |
Collection-like interface for aggregates (DDD) |
| Unit of Work |
Tracks changes; writes in single transaction |
Object-Relational
| Pattern |
Description |
| Identity Map |
Ensures each DB row loaded once per session |
| Lazy Load |
Defer loading until accessed |
| Metadata Mapping |
ORM config via annotations/XML |
Web Presentation
| Pattern |
Description |
| MVC |
Model-View-Controller separation |
| Page Controller |
One controller per page/action |
| Front Controller |
Single entry point dispatches to handlers |
| Template View |
HTML with embedded markers |
Distribution
| Pattern |
Description |
| Remote Facade |
Coarse-grained interface for remote access |
| Data Transfer Object |
Serializable data carrier for remote calls |
Concurrency
| Pattern |
Description |
| Optimistic Lock |
Version field; retry on conflict |
| Pessimistic Lock |
DB lock; blocks others |
Session State
| Pattern |
Description |
| Client Session State |
Store in client (cookie, localStorage) |
| Server Session State |
Store in server memory/DB |
| Database Session State |
Store in DB |
Anti-Patterns (Avoid)
| Anti-Pattern |
Description |
Better Approach |
| God Object |
One class does everything |
Decompose by responsibility |
| Anemic Domain Model |
Data bags + separate services |
Rich domain model (DDD) |
| Spaghetti Code |
No structure; tangled dependencies |
Layered/hexagonal architecture |
| Copy-Paste Programming |
Duplicate code instead of abstraction |
Extract common; DRY (knowledge) |
| Golden Hammer |
Favorite pattern used everywhere |
Right tool for the job |
| Premature Optimization |
Complex code for unmeasured gains |
Measure first; optimize bottlenecks |
| YAGNI Violation |
Building for imaginary futures |
Build for current requirements |
| Pattern Overload |
Patterns for pattern's sake |
Solve the problem simply |
Pattern Selection Guide
| Problem |
Consider |
| Need to create objects flexibly |
Factory, Builder, Prototype |
| Need to compose objects |
Composite, Decorator |
| Need to simplify interface |
Facade, Adapter |
| Need to change behavior dynamically |
Strategy, State, Decorator |
| Need to decouple sender/receiver |
Command, Observer, Mediator |
| Need to traverse structures |
Iterator, Visitor |
| Need to manage algorithm variations |
Strategy, Template Method |
| Need to handle cross-cutting concerns |
Decorator, Proxy, Aspect |
Modern Pattern Evolution
Functional Alternatives
| OO Pattern |
Functional Equivalent |
| Strategy |
Higher-order functions |
| Decorator |
Function composition |
| Observer |
Event streams (RxJS, Reactor) |
| Command |
Data + pure functions |
| Visitor |
Pattern matching / ADTs |
Cloud-Native Patterns
| Pattern |
Purpose |
| Circuit Breaker |
Fail fast; prevent cascade failures |
| Bulkhead |
Isolate resources; limit blast radius |
| Retry with Backoff |
Transient fault handling |
| Timeout |
Bound wait time |
| Rate Limiter |
Protect downstream |
| Cache-Aside |
Read performance |
| Event Sourcing |
Audit trail; temporal queries |
| CQRS |
Separate read/write models |
| Saga |
Distributed transactions |
| Sidecar |
Cross-cutting concerns in separate process |
Using Patterns Wisely
- Learn the names — Shared vocabulary for design discussions
- Recognize the problem — Pattern matches problem, not reverse
- Apply judiciously — Simplicity > pattern conformance
- Compose patterns — Real systems combine many
- Know anti-patterns — Diagnostic labels for code smells
"Patterns are useful shared names for recurring solutions. Reach for one when the problem actually matches it. Don't impose patterns to look sophisticated — pattern-heavy code is often a sign of over-engineering."
- Design Principles — Principles underlying patterns
- Architectural Styles — Patterns at architecture level
- Integration Patterns — Communication patterns
- Resilience Patterns — Fault tolerance patterns
- Concurrency Patterns — Threading/async patterns
- Domain Driven Design — DDD tactical patterns
Sources: Design Patterns (GoF), Patterns of Enterprise Application Architecture (Fowler), Cloud Design Patterns (Microsoft/AWS), Software Engineering Guide, SourceMaking, Refactoring.Guru