CREATIONAL PATTERNS III
● Chapter 06 · L03 — Software Design & Architecture

Blueprints for objects that build themselves — and objects there's only one of.

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.

Patterns
Builder · Singleton
Category
Creational
Core Question
How is it built? How many exist?
Memory Key
🍔 Recipe · 🔑 One Key
00
Before we go deeper

Quick recap of what came before

Chapter 06 already covered two creational patterns. Keep them straight with one line each — they're the setup for why Builder and Singleton exist.

🏭

Abstract Factory

Mnemonic: "Whole family, one order." Creates several related objects at once (e.g. CPU + Monitor + Keyboard) so they're always a matching set.

🧩

Factory Method

Mnemonic: "One product, many recipes." A single creation method, overridden by subclasses to decide which concrete class gets built.

➡️

What's new today

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.


01
Creational Pattern

The Builder Pattern

Intent: separate the construction of a complex object from its representation, so the same construction steps can produce different final results.

🍔
Memory Hook

"Same Recipe, Different Burger."

You always follow the same steps — add bun, add patty, add sauce — but a Beef Builder and a Chicken Builder follow those steps with different ingredients. Same process, different product. That is the Builder pattern.

The 4 roles — remember them as "Dad Builds Cool Products"

D
🎬

Director

Orchestrates the steps in order. Doesn't know how each step works — just the sequence.

B
📋

Builder (interface)

Declares the multistep API: buildPartA(), buildPartB(), getResult().

C
🛠️

Concrete Builder

One class per variant — implements each step its own way, holds the in-progress object.

P
📦

Product

The final complex object that comes out the other end, fully assembled.

Flow: Client picks a Concrete Builder → hands it to the Director → Director calls the steps in sequence → Client asks the builder for the finished Product.
Client
chooses the variant
Director
runs construct()
Concrete Builder
executes each step
Product
getResult()

Worked example: the Burger Builder

Beef and Chicken burgers follow the exact same 3 steps (bun → patty → sauce) with different ingredients — a clean, minimal Builder implementation:

Builder.java — the shared interface
interface BurgerBuilder { void addBun(); void addPatty(); void addSauce(); Burger getBurger(); } // Concrete builder — one recipe class BeefBurgerBuilder implements BurgerBuilder { Burger burger = new Burger(); public void addBun() { burger.bun = "Sesame Bun"; } public void addPatty() { burger.patty = "Beef Patty"; } public void addSauce() { burger.sauce = "BBQ Sauce"; } public Burger getBurger() { return burger; } }
Chef.java — the director
class Chef { private BurgerBuilder builder; Chef(BurgerBuilder b) { builder = b; } // same 3 steps, every time public Burger construct() { builder.addBun(); builder.addPatty(); builder.addSauce(); return builder.getBurger(); } } // client Chef chef = new Chef(new BeefBurgerBuilder()); Burger beef = chef.construct();

Why bother?

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 vs. Abstract Factory

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.


02
Creational Pattern

The Singleton Pattern

Intent: ensure a class has only one instance, and provide a global access point to it.

🔑
Memory Hook

"One Key, One Lock, One Door."

No matter how many times you ask for the key, you get handed back the same one. There is no spare, and there is no way to cut a new one from outside.

🔑 🔑 🔑 🔑 🔑

every call to getInstance() hands back the one glowing key — never a new one

3 ingredients — remember "Locked, Instance, Door"

L
🔒

Private Constructor

Blocks anyone outside the class from typing new Singleton().

I
📌

Static Instance

One private field holds the single object, alive for the program's whole run.

D
🚪

getInstance() "Door"

The only public, static way in — creates the instance once, then always returns it.

Designing one, in 3 steps

Make the constructor private

Nobody outside the class can instantiate it directly.

Add a private static reference to hold the one instance

This is the single "slot" the object will ever live in.

Expose a public static getInstance()

It creates the object the first time it's called, and simply returns it every time after.

Real scenario: one logger for a banking app

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.

EventLogger.java
public class EventLogger { private static EventLogger instance; // L — locked: private constructor private EventLogger() {} // D — the one door in public static EventLogger getInstance() { if (instance == null) { instance = new EventLogger(); // I — created once } return instance; } public void log(String message) { System.out.println("Log: " + message); } } // used identically from anywhere in the app: EventLogger.getInstance().log("User Alice logged in."); EventLogger.getInstance().log("Transferred $250 from Alice to Bob.");

Benefit

Controlled, centralized access to the one instance — no duplicate loggers, no conflicting writes.

⚠️

Watch out

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.


+1
From the practice question

Bonus: Prototype Pattern

Not a full topic this chapter, but it showed up in the practice exercise (Circle/Square shapes) — worth two lines of memory.

🧬
Memory Hook

"Don't Build From Scratch — Clone It."

Instead of new Circle(10) every time, you call circle.clone() to duplicate an existing object — useful when creating an object from scratch is expensive or repetitive.

Prototype in one breath
interface Shape { Shape clone(); } class Circle implements Shape { int radius; Circle(int r) { radius = r; } public Shape clone() { return new Circle(radius); } // copy, not construct }

📎
One table to rule the exam

Cheat sheet

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

🧠
Active recall

Flip-card review

tap a card to flip it

Q1What does the Builder pattern separate from what?
Construction (the steps) from representation (the final look) — same steps, different outputs.
Q2Who orchestrates the build steps in order?
The Director — it calls the builder's steps in sequence but doesn't know how each step works internally.
Q3Builder vs. Abstract Factory — what's the real difference?
Builder = one object, step-by-step. Abstract Factory = a whole family of related objects, all at once.
Q4What 2 things guarantee a class has only one instance?
A private constructor (blocks "new" from outside) + a static getInstance() that creates it only once.
Q5What's the main drawback of the classic Singleton?
It's not safe in multithreaded environments — two threads can create two instances at once unless synchronized.
Q6Why use Builder over one giant constructor?
A giant constructor with many parameters is hard to read, hard to customize, and easy to get wrong — Builder assembles it step by step instead.
Q7To add a new burger flavor, what do you change?
Just add one new Concrete Builder class — the Director, Client, and Product stay untouched. That's the extensibility win.
Q8What does Prototype's clone() avoid?
Rebuilding an object from scratch — it copies an existing instance instead of calling "new" again.