Design Patterns - Creational
Singleton, Factory Method, Abstract Factory, Builder, and Prototype.
Deutsche Übersetzung in Arbeit
Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.
Auf dieser Seite
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.
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(); }
}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.
Abstract Factory - families of related objects
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();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
| Pattern | Solves | One-liner |
|---|---|---|
| Singleton | Need exactly one instance | "There can be only one" |
| Factory Method | Subclass decides the type | "Order the special" |
| Abstract Factory | Families of matching objects | "All-or-nothing theme" |
| Builder | Complex step-by-step construction | "Build it your way" |
| Prototype | Copy 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.