CMD Guide
HomeOO & Low-Level Design

Creational

Step 4 in the OO & Low-Level Design path · 7 concepts · 0 problems

0 / 7 complete

📘 Learn Creational from zero

Start from the problem. Normal object creation is new Car(). That looks harmless, but the keyword new hardwires the exact concrete class into the code that uses it. Creational patterns answer one question: how do we create objects without our code being rigidly glued to specific concrete classes — and without making construction itself a mess?

Analogy: a restaurant kitchen. A customer does not assemble their own burger. They give an order to a kitchen and receive a finished dish — they never touch the raw ingredients or know the recipe. If the chef swaps beef for a plant patty, the customer's experience is unchanged. The customer is decoupled from how the food is built. That separation between "what I want" and "how it is built" is the whole family of creational patterns.

Worked example. Suppose a game spawns enemies:

Now imagine an Orc must always come with an Orc-themed weapon and shield, never a Troll's. Bundling those related products is Abstract Factory. If Orc construction took 50 mostly-optional fields, you would Builder it. If a fully configured exemplar already exists, you Prototype (clone) it. If only one global spawner may exist, that spawner is a Singleton.

Key insight: every creational pattern is one tactic for the same GoF goal — program to an interface, not an implementation, by centralizing and abstracting the new.

✨ Added by the guide to build intuition — not from the source course.

🎯 Guided practice

  1. Easy — Make a Logger a Singleton. Requirement: every part of an app must write to the same log buffer; two loggers would split the logs.

    Step 1 — Spot the trigger: "exactly one, shared access" then Singleton.

    Step 2 — Block other instantiation: make the constructor private so no caller can run new Logger().

    Step 3 — Provide the single access point: a static getInstance() returning the one stored instance — created on first call (lazy) or eagerly as a static final field.

    Step 4 — Handle concurrency: if two threads call lazy getInstance() at once, you can create two objects. Fix with eager init, the initialization-on-demand holder idiom (class-loading guarantees one), or double-checked locking on a volatile field. Say this out loud — interviewers reliably probe thread safety, and "DCL without volatile" is a classic trap.

    Takeaway: Singleton = private constructor + static accessor + a safely-published single instance.

  2. Medium — Build a cross-platform UI toolkit. Requirement: render a Button and a Checkbox that match the OS — all macOS, or all Windows, never mixed.

    Step 1 — Recognize the family: two related products (Button, Checkbox) that must vary together by one theme then this is Abstract Factory, not a lone Factory Method.

    Step 2 — Define abstract products: interfaces Button and Checkbox, with concretes MacButton/WinButton and MacCheckbox/WinCheckbox.

    Step 3 — Define the abstract factory: interface GUIFactory with createButton() and createCheckbox(). Two implementations: MacFactory returns Mac products; WinFactory returns Win products. Since each factory only ever returns one family, mixing is impossible by construction.

    Step 4 — Wire it once: at startup pick GUIFactory f = onMac ? new MacFactory() : new WinFactory();. The rest of the app calls f.createButton() / f.createCheckbox() and never references a concrete class.

    Step 5 — Verify the win: adding a Linux theme = one new factory plus its products, with zero changes to app code (Open/Closed Principle).

    Takeaway: Abstract Factory groups several creation methods (each often a Factory Method) so whole families of products stay mutually consistent.

✨ Added by the guide — work these before the full problem set.

Lessons in this topic

🧠 Review & recall

Active recall is what moves a topic into long-term memory. Flip each card before revealing, then test yourself — your results are saved on this device.

Flashcard
What single GoF goal unifies all creational patterns, and what is the underlying problem they solve?
tap to reveal →
They all 'program to an interface, not an implementation, by centralizing and abstracting the new keyword.' The problem: writing new ConcreteClass() hardwires the exact concrete class into the calling code, gluing it rigidly to specific implementations.
💡 All creational patterns = 'abstract away new.'
Flashcard
What three structural pieces define a Singleton, and what is the classic concurrency trap?
tap to reveal →
A private constructor (blocks new), a private static instance field, and a public static getInstance() returning the one shared instance. The classic trap is double-checked locking without a volatile field; safe options are eager init, the initialization-on-demand holder idiom, or DCL on a volatile field.
💡 Private ctor + static accessor + safely-published instance; 'DCL needs volatile.'
Flashcard
How does the Factory Method pattern differ from a Simple Factory, and what are its four class diagram roles?
tap to reveal →
Factory Method declares an abstract creation method on a Creator base class that subclasses (ConcreteCreator) override to choose the product; Simple Factory just centralizes the new in one method/if-chain. The four roles are Product, ConcreteProduct, Creator, and ConcreteCreator.
💡 Subclasses pick the product. P, CP, Creator, CC.
Flashcard
When do you reach for Abstract Factory instead of a single Factory Method?
tap to reveal →
When you must create a whole family of related/dependent products that must stay mutually consistent (e.g. a Button AND a Checkbox that are all macOS or all Windows, never mixed). Abstract Factory is a 'factory of factories' — each ConcreteFactory only ever returns one consistent family, so mixing is impossible by construction.
💡 Families that vary together = factory of factories.
Flashcard
What problem does the Builder pattern solve, and what are its four roles?
tap to reveal →
It constructs a complex object step by step, separating construction from representation, so the same process can build different representations — ideal when an object has many optional parameters (e.g. a Pizza with size/crust/toppings) instead of telescoping constructors. Roles: Director, Builder, ConcreteBuilder, Product.
💡 Step-by-step build for many optional params: Director, Builder, ConcreteBuilder, Product.
Flashcard
When is the Prototype pattern the right choice, and what is the shallow-vs-deep distinction?
tap to reveal →
Use it when creating a new instance is more expensive/complex than copying an existing one, or when the object type isn't known until runtime — you clone a configured prototype instead of building from scratch. A shallow clone copies only the object's immediate properties; a deep clone recursively copies the object and everything it references.
💡 Clone an exemplar instead of rebuilding; shallow = top level, deep = recursive.
Q1. A game centralizes enemy creation in one method with an if/else chain (new Orc() / new Troll()). To add a Dragon without editing every call site, the lesson's recommended Factory Method approach is to:
Q2. You must render a Button and a Checkbox that are all macOS or all Windows, never mixed. Which pattern guarantees this consistency by construction?
Q3. According to the lesson, which is a genuine drawback (con) of the Singleton pattern?
Q4. An object is expensive to construct, must be created dynamically, and many near-identical copies are needed at runtime. Which pattern fits best?
Q5. In the lesson's Builder pizza example, which class issues the build steps in order (buildSize, buildCrust, buildToppings) to the builder?