Creational Design Patterns
Creational patterns abstract the instantiation process — they make a system independent of how its objects are created, composed, and represented.
%%{init: {'theme': 'base', 'themeVariables': {'fontSize': '13px', 'fontFamily': 'Inter, -apple-system, sans-serif'}, 'flowchart': {'nodeSpacing': 30, 'rankSpacing': 50, 'padding': 12, 'curve': 'basis'}, 'sequence': {'actorMargin': 60, 'messageMargin': 40}, 'class': {'padding': 12}}}%%
flowchart LR
C["🟡 Creational"] -->|"asks"| Q["❓ How to create?"]
Q -->|"goal"| G1["✅ Hide logic"] --> G2["✅ Flexible"] --> G3["✅ Decoupled"]
style C fill:#FFF3E0,stroke:#E65100,stroke-width:2px,color:#000
style Q fill:#FEF3C7,stroke:#D97706,color:#000
style G1 fill:#E8F5E9,stroke:#2E7D32,color:#000
style G2 fill:#E8F5E9,stroke:#2E7D32,color:#000
style G3 fill:#E8F5E9,stroke:#2E7D32,color:#000 Why Creational Patterns?
As systems grow, hardcoding object creation (new ConcreteClass()) everywhere leads to:
- Tight coupling — changing one class means modifying dozens of files
- Inflexibility — can't swap implementations without rewriting code
- Duplication — creation logic scattered and repeated
Creational patterns solve this by encapsulating which classes get instantiated and hiding how instances are assembled.
The 5 Creational Patterns
| # | Pattern | When to Use | Key Idea |
|---|---|---|---|
| 1 | Singleton | Need exactly ONE instance | Private constructor + static access |
| 2 | Factory Method | Let subclasses decide what to create | Interface for creation, subclass implements |
| 3 | Abstract Factory | Need families of related objects | Factory of factories |
| 4 | Builder | Complex objects with many options | Step-by-step construction |
| 5 | Prototype | Expensive creation, clone instead | Copy existing objects |
Choosing the Right Pattern
%%{init: {'theme': 'base', 'themeVariables': {'fontSize': '13px', 'fontFamily': 'Inter, -apple-system, sans-serif'}, 'flowchart': {'nodeSpacing': 30, 'rankSpacing': 50, 'padding': 12, 'curve': 'basis'}, 'sequence': {'actorMargin': 60, 'messageMargin': 40}, 'class': {'padding': 12}}}%%
flowchart LR
Start{"🤔 How to create?"}
Start -->|"one instance?"| Sing(["🎯 Singleton"])
Start -->|"pick type at runtime?"| Fact(["🏭 Factory"])
Fact -->|"whole family?"| AF(["🏗️ Abstract Factory"])
Start -->|"many options?"| Build(["🔨 Builder"])
Start -->|"expensive? clone!"| Proto(["🧬 Prototype"])
style Start fill:#FEF3C7,stroke:#D97706,stroke-width:2px,color:#000
style Sing fill:#E3F2FD,stroke:#1565C0,color:#000
style Fact fill:#E8F5E9,stroke:#2E7D32,color:#000
style AF fill:#FFF3E0,stroke:#E65100,color:#000
style Build fill:#FFF8E1,stroke:#F9A825,color:#000
style Proto fill:#FCE4EC,stroke:#C62828,color:#000 Key Principle
All creational patterns share one goal: program to an interface, not an implementation. The client never needs to know the exact class being instantiated — only the contract it fulfills.