Design Patterns (GoF)
Design Patterns (GoF)
Gang of Four Software Design Patterns
1. Overview of GoF Design Patterns: A System of Proven, Reusable Solutions to Recurring Design Problems
flowchart LR
A["Recurring design problems<br/>(duplication, coupling, maintainability)"] --"Apply 23<br/>proven patterns"--> B["Creational, structural,<br/>and behavioral pattern families"] --"Flexible,<br/>reusable design"--> C["Software architecture<br/>resilient to change"]
style A fill:#FFEBEE,stroke:#D32F2F,color:#000
style B fill:#E3F2FD,stroke:#1976D2,color:#000
style C fill:#E8F5E9,stroke:#388E3C,color:#000
Definition: A body of design knowledge consisting of 23 software design patterns cataloged by Erich Gamma and three co-authors (the “Gang of Four”), classifying proven solutions to recurring object-oriented design problems into Creational, Structural, and Behavioral patterns.
Characteristics: (Design reusability) A reusable solution at the design level, independent of any specific language or technology. (A shared design language) Improves communication efficiency among developers through a common design vocabulary (pattern names). (Complementary use) Used complementarily with SOLID principles and Clean Architecture.
2. Core Structure of GoF Design Patterns
a. Creational, Structural, and Behavioral Patterns
flowchart TD
subgraph R1[""]
direction LR
CR["Creational Patterns<br/>encapsulate object creation<br/>flexible instance creation"]
ST["Structural Patterns<br/>compose classes/objects<br/>into larger structures"]
BE["Behavioral Patterns<br/>distribute responsibility/algorithms<br/>and collaboration between objects"]
end
style CR fill:#E3F2FD,stroke:#1976D2,color:#000
style ST fill:#F3E5F5,stroke:#7B1FA2,color:#000
style BE fill:#FFF3E0,stroke:#F57C00,color:#000
style R1 fill:none,stroke:none
Creational Patterns (5)
| Pattern | Purpose | Key Characteristics |
|---|---|---|
| Singleton | Guarantee only one instance of a class | Provides a global access point, shares a resource |
| Factory Method | Delegate object creation to a subclass | Separates creation code from usage code |
| Abstract Factory | Consistently create a family of related objects | Creates platform-independent UI components |
| Builder | Construct a complex object step by step | Produces varied results via the same process |
| Prototype | Create a new object by cloning an existing one | Copying objects that are expensive to initialize |
Structural Patterns (7)
| Pattern | Purpose | Key Characteristics |
|---|---|---|
| Adapter | Connect incompatible interfaces | Legacy system integration, acts as a wrapper |
| Decorator | Dynamically add functionality to an object | Extends responsibility without inheritance, stackable |
| Facade | Provide a simple interface to a complex subsystem | API Gateway, library wrapping |
| Proxy | Act as a surrogate/controlled access to another object | Lazy loading, access control, caching |
| Composite | Represent part-whole hierarchies as a tree | File systems, UI component trees |
| Bridge | Vary abstraction and implementation independently | Separates different implementations per platform |
| Flyweight | Efficiently share large numbers of similar objects | Game particles, character font caching |
Behavioral Patterns (11)
| Pattern | Purpose | Key Characteristics |
|---|---|---|
| Observer | Automatically notify many objects of a state change | Event-driven, Pub/Sub-based |
| Strategy | Encapsulate an algorithm to make it swappable | Removes if-else chains, swaps algorithms at runtime |
| Command | Encapsulate a request as an object | Undo support, queuing/logging |
| Template Method | Define an algorithm’s skeleton, delegate details | Preserves the common flow, isolates variation points |
| Iterator | Standardize traversal of a collection | Sequential access without exposing internal structure |
| Chain of Responsibility | Pass a request along a chain of handlers | Middleware, filter pipelines |
| State | Change behavior based on an object’s state | Implements a finite state machine (FSM) |
b. Key Pattern Examples — Singleton, Observer
Singleton — Guaranteeing a Single Instance
flowchart LR
C1["Client A"] --> S["Singleton Instance<br/>(only one exists)<br/>config manager, DB connection,<br/>log manager"]
C2["Client B"] --> S
C3["Client C"] --> S
style S fill:#1E3A5F,stroke:#1E3A5F,color:#fff
| Category | Description |
|---|---|
| When to apply | When global state management is needed and a single instance must be guaranteed |
| Advantages | Resource sharing, memory savings, consistent state access |
| Caveats | Requires double-checked locking in multithreaded environments, harder to test |
| Common examples | Config, DB connection pool, Logger, thread pool |
Observer — Automatic Notification of State Change
flowchart LR
PUB["Subject (Publisher)<br/>a state change occurs<br/>manages the subscriber list"]
subgraph OBS["Observer (Subscriber)"]
direction TB
O1["Observer A<br/>(email notification)"]
O2["Observer B<br/>(SMS notification)"]
O3["Observer C<br/>(push notification)"]
end
PUB --"notify()"--> O1
PUB --"notify()"--> O2
PUB --"notify()"--> O3
style PUB fill:#1E3A5F,stroke:#1E3A5F,color:#fff
style O1 fill:#E3F2FD,stroke:#1976D2,color:#000
style O2 fill:#F3E5F5,stroke:#7B1FA2,color:#000
style O3 fill:#FFF3E0,stroke:#F57C00,color:#000
| Category | Description |
|---|---|
| When to apply | When a change in one object’s state must propagate to several other objects |
| Advantages | Loose coupling, dynamic add/remove of subscribers, enables event-driven architecture |
| Common examples | GUI event handling, Kafka Pub/Sub, state management (Redux), Spring ApplicationEvent |
3. Expected Benefits and Application of GoF Design Patterns
| Category | Expected Benefits | Application and Practical Use |
|---|---|---|
| Code quality | Applying proven patterns reduces coupling and increases cohesion | Remove conditionals with Strategy, separate responsibilities with Decorator |
| Maintainability | Flexible design minimizes the blast radius of change | Implement event-driven extensibility with Observer/Command patterns |
| Communication efficiency | Pattern names concisely convey design intent | Reduce communication cost in code reviews and design docs by using pattern names |
| Architecture integration | Combines with MSA/Clean Architecture to strengthen extensibility | Inject dependencies with Factory, simplify microservice APIs with Facade |