2.2.10Design Principles

Design Patterns — Creational - Singleton, Factory Method, Abstract Factory, Builder, Prototype

2,055 words9 min readdifficulty · medium5 backlinks

The 5 GoF creational patterns, in one breath:

Pattern One-line job The question it answers
Singleton Exactly one instance, global access "How do I guarantee only one?"
Factory Method A method subclasses override to choose the class "Which subclass do I instantiate?"
Abstract Factory A family of related products built together "How do I keep a kit consistent?"
Builder Build a complex object step by step "Too many constructor args?"
Prototype Create new objects by cloning an existing one "New object is like this one?"
Figure — Design Patterns — Creational -  Singleton, Factory Method, Abstract Factory, Builder, Prototype

1. Singleton

WHY: Some resources are inherently single — a config registry, a logging hub, a connection pool. Two copies would cause inconsistent state.

HOW (derive from first principles):

  1. To prevent others making instances → make the constructor private.
  2. To still give one out → a static method returns it.
  3. To store it → a static field holds the single instance.
class Logger {
    private static Logger instance;        // the one slot
    private Logger() {}                     // nobody else can `new`
    public static Logger getInstance() {    // global access point
        if (instance == null)               // lazy: build on first use
            instance = new Logger();
        return instance;
    }
}

Why instance == null check? So we build lazily (only when first needed) and only once.


2. Factory Method

WHY: A Dialog knows it needs a button, but a WindowsDialog needs a Windows button and a WebDialog needs an HTML button. The base class shouldn't new WindowsButton().

HOW: Replace the direct new with a call to an overridable method.

abstract class Dialog {
    abstract Button createButton();        // <-- factory method (the hook)
    void render() {
        Button b = createButton();         // base logic, no concrete class!
        b.onClick(); b.draw();
    }
}
class WindowsDialog extends Dialog {
    Button createButton() { return new WindowsButton(); }
}

Why is render() in the base class? Because the workflow is shared; only the product choice varies. That's the whole point — vary one decision via subclassing.


3. Abstract Factory

WHY: Factory Method makes one product. But a Windows UI needs Windows buttons AND checkboxes AND menus — they must match. Abstract Factory groups several factory methods so the whole kit is consistent.

interface GUIFactory {                     // the family
    Button   createButton();
    Checkbox createCheckbox();
}
class WinFactory implements GUIFactory {
    public Button   createButton()   { return new WinButton(); }
    public Checkbox createCheckbox() { return new WinCheckbox(); }
}
// client takes a GUIFactory, never knows which OS

Why an object (factory) not subclassing? Because you swap the whole family at runtime by passing a different factory object. Factory Method varies by subclass; Abstract Factory varies by composition.


4. Builder

WHY: A constructor with 8 optional parameters → new Pizza(true,false,true,...) is unreadable ("telescoping constructors"). Builder names each step.

Pizza p = new Pizza.Builder()
    .size("L")
    .addCheese()
    .addOlives()
    .build();          // build() returns the finished, validated object

Why build() at the end? So the object is immutable and fully validated only when assembly completes — no half-built objects leak out.


5. Prototype

WHY: When construction is expensive (heavy DB load, config parsing) or you only have a runtime object and want a duplicate, clone it.

interface Shape { Shape clone(); }
class Circle implements Shape {
    int r;
    public Shape clone() { Circle c = new Circle(); c.r = this.r; return c; }
}

Recall Feynman: explain to a 12-year-old

Imagine a toy factory. Instead of building each toy with your bare hands every time (new), you use machines.

  • Singleton: one special vending machine in the whole school — everyone uses that same one.
  • Factory Method: a machine with a slot; a kid decides whether a car or a robot pops out.
  • Abstract Factory: a machine that always gives a matching set — red car with red garage, never a mismatch.
  • Builder: a sandwich shop where you say "bread, then cheese, then done!" step by step.
  • Prototype: a photocopier — you have one drawing and press copy to get more.

Flashcards

What problem do creational patterns solve?
They decouple what object you need from how it's constructed, centralizing creation logic.
How does a Singleton prevent external instantiation?
By making the constructor private and exposing a static getInstance().
Why is the naive lazy Singleton not thread-safe?
Two threads can both pass the instance == null check and each create an instance.
Best thread-safe lazy Singleton idiom in Java?
Initialization-on-demand holder (static nested class with a static final field).
Factory Method varies the product by ___?
Subclassing (overriding the creation method).
Abstract Factory varies the product family by ___?
Composition (passing a different factory object at runtime).
Key difference: Factory Method vs Abstract Factory?
Factory Method makes ONE product via subclass; Abstract Factory makes a matching FAMILY via an object.
What pain does Builder cure?
Telescoping constructors / many optional parameters; builds an immutable, validated object via build().
Why must Prototype often use deep copy?
A shallow copy shares nested mutable references, so mutating one object corrupts its clone.
When prefer Prototype over a constructor?
When construction is expensive or you only have a runtime instance to duplicate.
Why is Singleton sometimes an anti-pattern?
It's global mutable state that hides dependencies and harms testability; prefer DI.

Connections

  • Design Principles — patterns are SOLID in action (esp. Open/Closed and Dependency Inversion).
  • Factory Method is a special case used inside Abstract Factory.
  • Builder vs Prototype — build fresh vs copy existing.
  • Singleton often combined with Abstract Factory (one global factory).
  • Structural Patterns and Behavioral Patterns — the other two GoF categories.
  • Dependency Injection — modern alternative to Singleton.

Concept Map

decouples

replaces

includes

includes

includes

includes

includes

guarantees

risk

fix

naive lazy unsafe

subclass chooses

builds

assembles

creates by

Creational Patterns

What vs How wall

Scattered new calls

Singleton

Factory Method

Abstract Factory

Builder

Prototype

One instance + global access

Global mutable state

Prefer dependency injection

Holder idiom thread-safe

Which subclass to build

Consistent product family

Complex object step by step

Cloning existing object

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Creational patterns ka core idea simple hai: jab bhi aap seedha new SomeClass() likhte ho, aapka code us concrete class ke saath chipak jaata hai. Kal ko agar aapko doosri class chahiye, ya sirf ek hi shared instance chahiye, ya bahut saare optional fields ke saath object banana hai — to har jagah new change karna padega. In patterns ka kaam hai ek deewaar khadi karna "mujhe kya object chahiye" aur "wo banta kaise hai" ke beech. Construction ka logic ek hi jagah rahta hai.

Paanchon ko ek line mein yaad rakho: Singleton = poore program mein sirf ek hi instance (jaise ek hi config object). Factory Method = base class ek method deti hai jise subclass override karke decide karti hai kaunsi class banegi. Abstract Factory = ek poora matching family banata hai — Windows button ke saath Windows checkbox, mismatch kabhi nahi. Builder = jab constructor mein 8 arguments ho jaayein to step-by-step .addCheese().build() style mein object banao. Prototype = naya object banane ke bajaye purane ko clone() kar lo.

Sabse common galti Singleton mein hoti hai — log sochte hain naive lazy version thread-safe hai, par do threads ek saath null check pass karke do instance bana dete hain; iska fix hai holder idiom. Prototype mein dhyaan rakho ki shallow copy nested objects share kar leti hai, isliye deep copy chahiye. Aur yaad rakho: Singleton zyada use karna anti-pattern ban jaata hai kyunki wo global mutable state hai — testing mushkil ho jaati hai, isliye Dependency Injection prefer karo.

Go deeper — visual, from zero

Test yourself — Design Principles

Connections