A rebuilt, memorable pass through Builder and Singleton — the two creational patterns after Abstract Factory and Factory Method. Every section carries a mnemonic so it sticks past the exam.
Chapter 06 already covered two creational patterns. Keep them straight with one line each — they're the setup for why Builder and Singleton exist.
Mnemonic: "Whole family, one order." Creates several related objects at once (e.g. CPU + Monitor + Keyboard) so they're always a matching set.
Mnemonic: "One product, many recipes." A single creation method, overridden by subclasses to decide which concrete class gets built.
Builder asks "how do I build one complex thing, step by step?" Singleton asks "how do I make sure only one exists, ever?" Neither is about families of objects — that was Abstract Factory's job.
Intent: separate the construction of a complex object from its representation, so the same construction steps can produce different final results.
Orchestrates the steps in order. Doesn't know how each step works — just the sequence.
Declares the multistep API: buildPartA(), buildPartB(),
getResult().
One class per variant — implements each step its own way, holds the in-progress object.
The final complex object that comes out the other end, fully assembled.
Beef and Chicken burgers follow the exact same 3 steps (bun → patty → sauce) with different ingredients — a clean, minimal Builder implementation:
To add a Turkey Burger tomorrow, you write one new concrete builder. The Director, the Client, and the Product class don't change at all — that's the extensibility payoff.
Builder builds one complex object, one step at a time, and gives you fine control over when each part is created. Abstract Factory builds a family of separate, related objects, all in one shot. Different problem, same "creational" family.
Intent: ensure a class has only one instance, and provide a global access point to it.
every call to getInstance() hands back the one glowing key — never a new one
Blocks anyone outside the class from typing new Singleton().
One private field holds the single object, alive for the program's whole run.
The only public, static way in — creates the instance once, then always returns it.
Nobody outside the class can instantiate it directly.
This is the single "slot" the object will ever live in.
It creates the object the first time it's called, and simply returns it every time after.
Login, Transactions, and Notifications all need to log
events. If each created its own logger, you'd get scattered, conflicting log files. A Singleton
EventLogger gives every part of the app the exact same logger.
Controlled, centralized access to the one instance — no duplicate loggers, no conflicting writes.
The classic Singleton doesn't play well in multithreaded environments — two threads can race to create the instance at the same time unless it's synchronized.
Not a full topic this chapter, but it showed up in the practice exercise (Circle/Square shapes) — worth two lines of memory.
| Pattern | Solves | Key Method | Mnemonic |
|---|---|---|---|
| Abstract Factory | Creating a family of related objects together | createProductA(), createProductB()… | 🏭 Whole family, one order |
| Factory Method | Letting subclasses decide which class to instantiate | createProduct() | 🧩 One product, many recipes |
| Builder | Constructing one complex object step by step | buildPartX(), getResult() | 🍔 Same recipe, different burger |
| Singleton | Guaranteeing exactly one instance exists | getInstance() | 🔑 One key, one lock, one door |
| Prototype | Creating new objects by copying existing ones | clone() | 🧬 Don't build — clone it |
tap a card to flip it