CMD Guide
HomeOO & Low-Level DesignDesign Patterns Overview

Introduction

From plain new to a creational pattern

Creational patterns hide how objects are created so clients are not welded to concrete types. They are not a default. The honest starting point is always a plain constructor or new; reach for a pattern only when a real force appears. Two concrete forces are common:

// N = 1: plain new is the right choice
PaymentGateway gateway = new StripeGateway();

// N = 2: introduce a factory so callers do not hard-code a concrete type
PaymentGateway gateway = GatewayFactory.create("stripe");  // Simple Factory idiom

// Many optional fields: Builder beats a telescoping constructor
HttpRequest req = HttpRequest.builder()
    .url(url)
    .timeout(30_000)
    .retries(3)
    .header("Authorization", token)
    .build();

Simple Factory vs GoF Factory Method (do not confuse them)

Simple FactoryGoF Factory Method
ShapeOne class (often static) with a switch / map on a type keyAbstract Creator; subclasses override factoryMethod()
Add a productEdit the switch (not Open/Closed)Add a Creator subclass (Open/Closed)
Use whenFew, stable variants; quick wiringCreation logic varies with a Creator hierarchy / framework hooks
Not thisNot a GoF pattern — a useful idiomNot "any method named factory"
// Simple Factory — handy, not GoF
Transport t = TransportFactory.create("sea");  // switch inside

// GoF Factory Method — Creator subclasses choose the product
abstract class Logistics {
    protected abstract Transport createTransport();  // factory method
    void planDelivery() { createTransport().deliver(); }
}
class SeaLogistics extends Logistics {
    protected Transport createTransport() { return new Ship(); }
}

Deep dive and when-not (vs DI, Abstract Factory): Factory Method Pattern (FIX / creational deep page in this course).

Hostile-panel drill: defend your creational choice

The interviewer will not let you name a pattern in peace — they will attack the choice. Rehearse the two most common attacks aloud.

Q1. "You wrote GatewayFactory.create("stripe"). That's a switch on a string. Doesn't that violate Open/Closed — every new provider reopens the factory?"

A. Yes, for the switch-based Simple Factory they have a point: adding PayPal edits the switch, so the factory is not closed to modification. There are two honest escapes. (a) Move to a GoF Factory Method — a Creator subclass supplies the product, so a new provider is a new subclass, not an edit. (b) Keep the Simple Factory but replace the switch with a registry/map so adding a provider registers a key instead of editing control flow:

// OCP-clean Simple Factory: a registry, not a switch
Map<String, Supplier<PaymentGateway>> registry = new HashMap<>();
registry.put("stripe", StripeGateway::new);
registry.put("paypal", PayPalGateway::new);   // adding a provider = one line, no switch edit

PaymentGateway create(String key) {
    Supplier<PaymentGateway> s = registry.get(key);
    if (s == null) throw new IllegalArgumentException("unknown gateway: " + key);
    return s.get();
}

The registry closes the factory to modification (new providers register from outside) while staying a one-class idiom — you do not need a Creator hierarchy just to satisfy OCP.

Q2. "When is a factory the wrong tool entirely?"

A. When the caller just needs one dependency supplied and there is no creation logic and no WHICH-concrete decision to make. Then a factory is ceremony: plain constructor injection (DI) is simpler — hand the object its collaborator and let a composition root (or DI container) decide the concrete type once. A factory earns its keep only when the WHICH-concrete choice is non-trivial (varies by input, config, or environment) or must be centralized so callers stop hard-coding it. No variant selection, no assembly logic → DI beats any factory.

Common Creational Patterns

Common Creational Patterns

Why patterns matter

Design patterns are not libraries or syntax rules. They are shared names for recurring solutions so teams can discuss design without redrawing the same diagram. The value is not the pattern itself; it is the ability to say "this is a Factory Method" and have everyone understand the forces, structure, and consequences — including the Simple Factory trap.

How to read a pattern

Every pattern description should answer three questions in order:

  1. Problem. What design force makes simple code fail? (Example: many optional constructor parameters.)
  2. Structure. What classes collaborate and what are their responsibilities?
  3. Consequences. What do you gain and what do you pay? (Example: readable construction, but more classes.)

Pattern-selection flowchart

Start with plain constructor / plain new
        |
        v
Is there more than one concrete type that changes independently?
        | yes
        v
   Prefer Simple Factory if variants few/stable;
   GoF Factory Method if Creator hierarchy / hooks needed;
   Abstract Factory for product families
        | no
        v
Does the object have many optional or ordered parameters?
        | yes
        v
   Use Builder
        | no
        v
Must exactly one instance exist and be globally reachable?
        | yes
        v
   Use Singleton (and document why it is not a hidden dependency)
        | no
        v
   Keep the plain constructor

When a creational pattern is overkill

Creational patterns pay rent only when creation is non-trivial or varies. Costs include extra classes and files, indirection when reading code, and a composition root or factory to maintain. Skip them when there is exactly one simple concrete type and no realistic second variant — the rule of three applies here too. A LoggerFactory for a single Logger implementation, or a Singleton around a stateless helper, is speculative generality (YAGNI). Prefer constructor injection (DI) when you only need to supply a dependency and there is no Creator template logic. Use the plain constructor until a real second implementation or a genuine optional-parameter explosion arrives.

🤖 Don't fully get this? Learn it with Claude

Stuck on Introduction? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Introduction** (OO & Low-Level Design) and want to truly understand it. Explain Introduction from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Introduction** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Introduction** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Introduction** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes