Start Learning
Javaneer
Back to stage
Stage 5·Software Craftsmanship

Design Patterns - Creational

Singleton, Factory Method, Abstract Factory, Builder, and Prototype.

22 min readAdvanced
On this page

Design patterns are proven, reusable solutions to problems that come up again and again. They're a shared vocabulary - say "use a Builder" and any developer knows what you mean. Creational patterns deal with how objects are created.

Patterns are like cooking techniques

A chef doesn't reinvent how to make a sauce each time - they know techniques (reduction, emulsion) that solve recurring problems. Design patterns are those techniques for code: named, battle-tested approaches you apply when you recognize the situation.

Singleton - exactly one instance

Ensures a class has only one instance with a global access point. Useful for things there should only be one of: a configuration, a connection pool, a logger.

public class Config {
    private static final Config INSTANCE = new Config();
    private Config() { }                    // private - no one else can construct
    public static Config get() {            // the single access point
        return INSTANCE;
    }
}

Use Singletons sparingly

A Singleton is essentially global state - it can hide dependencies and make testing hard. Often, injecting a single shared instance via Dependency Injection is cleaner. Reach for the pattern only when one-and-only-one is a genuine requirement.

Factory Method - let subclasses decide what to create

Defines a method for creating objects, but lets subclasses choose the concrete type. It decouples "using an object" from "knowing exactly which class to make".

interface Transport { void deliver(); }
class Truck implements Transport { public void deliver() { } }
class Ship  implements Transport { public void deliver() { } }

abstract class Logistics {
    abstract Transport createTransport();   // the factory method

    void plan() {
        Transport t = createTransport();     // uses it without knowing the type
        t.deliver();
    }
}
class RoadLogistics extends Logistics {
    Transport createTransport() { return new Truck(); }
}
class SeaLogistics extends Logistics {
    Transport createTransport() { return new Ship(); }
}
A factory method is like ordering 'the daily special'

You ask the kitchen for "today's special" without knowing whether it's fish or pasta. The kitchen (subclass) decides what to actually make. You depend on the idea of a meal, not a specific dish.

Creates whole families of related objects without specifying their concrete classes. Think building a UI that must be all-macOS or all-Windows.

interface GuiFactory {
    Button createButton();
    Checkbox createCheckbox();
}
class MacFactory implements GuiFactory {
    public Button createButton() { return new MacButton(); }
    public Checkbox createCheckbox() { return new MacCheckbox(); }
}
class WinFactory implements GuiFactory {
    public Button createButton() { return new WinButton(); }
    public Checkbox createCheckbox() { return new WinCheckbox(); }
}

Pick one factory, and every product it makes matches the same family.

Builder - construct complex objects step by step

When an object has many optional parts, a Builder assembles it readably, avoiding giant constructors with a dozen arguments.

Pizza pizza = new Pizza.Builder()
        .size("large")
        .addTopping("mushroom")
        .addTopping("olive")
        .extraCheese(true)
        .build();
A Builder is like a sandwich order

You don't hand the sandwich maker all your choices in one confusing breath. You build it step by step: bread, then filling, then sauce, then 'done'. Each step is clear and order-independent, and you get exactly what you asked for.

Builders beat telescoping constructors

Compare new Pizza("large", true, false, "mushroom", "olive", null) - which argument is what? - with the fluent builder above. Builders make optional parameters readable and prevent the 'telescoping constructor' mess.

Prototype - clone an existing object

Creates new objects by copying an existing one, rather than building from scratch. Handy when construction is expensive or you want a pre-configured template.

record Document(String template, List<String> sections) {
    Document copy() {
        return new Document(template, new ArrayList<>(sections));  // clone
    }
}

Pattern summary

PatternSolvesOne-liner
SingletonNeed exactly one instance"There can be only one"
Factory MethodSubclass decides the type"Order the special"
Abstract FactoryFamilies of matching objects"All-or-nothing theme"
BuilderComplex step-by-step construction"Build it your way"
PrototypeCopy an existing object"Clone this"

Quick check

An object has many optional parameters and you want readable, flexible construction. Which creational pattern fits?

Key takeaways

  • Creational patterns govern how objects are created.
  • Singleton ensures a single instance - use sparingly, as it's global state.
  • Factory Method lets subclasses decide which concrete type to create.
  • Abstract Factory produces families of related, matching objects.
  • Builder constructs complex objects step by step, taming many optional parameters.
  • Prototype creates new objects by cloning an existing one.

Next: structural patterns, which deal with how objects are composed into larger structures.