SwadhyAI Notes

All Low-Level Design notes

Design Patterns

When to use a pattern

The interviewer asks for a parking lot. You start listing names: Strategy, Factory, Singleton, Observer, Decorator. Ten minutes later you still have no Ticket class. Patterns are names for recurring fixes. They are not a checklist to tick off.

The book named 23 patterns in three families. Five hide how objects are created. Seven hide how objects are wired together. Eleven hide how objects divide a job. Pick the family first; the pattern name comes after.

The four moves

1

Name the smell

What keeps changing, and who knows too much?

2

Name the family

Create, structure, or behavior — pick one first.

3

Name the pattern

Only if a simpler class or map will not do.

4

Show the extension point

A new type becomes a class, not a new if.

Family compass

What is actually varying?

Name the smell
Pick the family
Name one pattern
Creation varies
5 creational
Wiring varies
7 structural
The job varies
11 behavioral

comes first. Find the unstable part. Hide it behind a stable interface. Then pick the family. A is the proof: a new requirement becomes a new class, not a new if in the old one.

The smell is a switch. The pattern is a seam.

Use a pattern when you can name the in plain language. “Every new vehicle type edits three switches” is Factory Method. “Hourly, airport, and event fees keep landing in ParkingLot” is Strategy. “A payment SDK does not look like Payable” is Adapter. If you cannot name the pain in plain language, you do not need the pattern yet.

java
// Smell: every new fee rule edits ParkingLot.
class ParkingLot {
  Money fee(Ticket t, Instant exit) {
    if (t.kind() == Kind.HOURLY)  return hourly(t, exit);
    if (t.kind() == Kind.AIRPORT) return airport(t, exit);
    throw new IllegalArgumentException();
  }
}

// Seam: PricingStrategy is the named variation.
// That is Strategy — a behavioral pattern — not a creational one.
class ParkingLot {
  private final PricingStrategy pricing;
  ParkingLot(PricingStrategy pricing) { this.pricing = pricing; }
  Money fee(Ticket t, Instant exit) { return pricing.fee(t, exit); }
}

Notice the family. The switch was about how to compute a fee, not about which class to construct. That is behavioral. A factory would be the wrong first name even though both hide a switch.

All 23 Gang of Four patterns

Five creational, seven structural, eleven behavioral. Each card is a full page. Open the one that matches the smell — do not memorize the list as a checklist.

Behavioral — 11

Chain of Responsibility passes a request along handlers. Command turns “do this” into an object. Interpreter models a tiny language. Iterator walks a collection without exposing it. Mediator replaces a web of pairwise calls. Memento saves a snapshot. Observer notifies listeners. State lets the current state decide behavior. Strategy swaps an algorithm. Template Method fixes the skeleton and varies the steps. Visitor adds an operation across a stable tree of types.

Smell to family to pattern

SmellFamilyPattern
Which class to new keeps spreading.CreationalFactory Method
A matching family of products must stay consistent.CreationalAbstract Factory
Too many constructor args and optional parts.CreationalBuilder
A ready object already exists; reconstruct is messy.CreationalPrototype
Truly one process resource — and usually you do not want this.CreationalSingleton
Foreign type, wrong interface.StructuralAdapter
Two axes of change multiply into a class explosion.StructuralBridge
Leaf and tree must share one contract.StructuralComposite
Add behavior, keep the same interface.StructuralDecorator
Hide a noisy subsystem behind one entry point.StructuralFacade
Share the heavy, unchanged part of many objects.StructuralFlyweight
Stand-in for access, laziness, or a remote stub.StructuralProxy
A pipeline of handlers that may stop the walk.BehavioralChain of Responsibility
Queue, undo, or replay a request as an object.BehavioralCommand
A tiny language modeled as objects.BehavioralInterpreter
Walk a collection without leaking its structure.BehavioralIterator
Many-to-many chatter that needs one hub.BehavioralMediator
Undo without exposing private fields.BehavioralMemento
Notify listeners without naming them all.BehavioralObserver
Behavior changes with the current state.BehavioralState
Swap an algorithm without editing the context.BehavioralStrategy
Share a skeleton, vary the steps.BehavioralTemplate Method
Add an operation across a stable type tree.BehavioralVisitor

Cousins that get mixed up

Factory Method vs Abstract Factory vs Builder

Factory Method answers “which Vehicle?” Abstract Factory answers “which matching kit — Button plus Dialog plus Menu?” Builder answers “how do I assemble this one complex object with optional parts?” You can combine them: a report factory returns a PDF builder or an HTML builder.

Adapter vs Decorator vs Proxy vs Facade

Adapter changes the shape so a foreign type matches yours. Decorator keeps the shape and adds behavior. Proxy keeps the shape and controls access, laziness, or a remote hop. Facade does not translate one type — it hides many types behind one simple entry point.

Strategy vs State vs Template Method vs Command

Strategy swaps an algorithm the caller chooses. State lets the object’s current state choose the next behavior. Template Method fixes the order of steps and varies hooks. Command turns the request itself into an object you can queue or undo.

Command vs Memento

Command remembers an action and how to reverse it. Memento remembers a snapshot of state and how to restore it, without knowing what changed. Chess often uses both.

Common mistake

Treating 23 names as a checklist

A design that “uses” Singleton, Factory, Observer, and Decorator in forty-five minutes is usually a God object with extra types. Name the variation. Use one or two patterns. Leave the rest unnamed.

Common mistake

Starting with the pattern instead of the smell

“I will use Abstract Factory” is not an answer. “Vehicle types keep multiplying and three controllers each have a switch” is. Then Factory Method — or a registry — is the fix.

Useful extras that are not GoF

Machine-coding rounds also reward a few names that are not in the 23. Null Object is a do-nothing implementation. Specification composes rules. Registry looks up a handler by name. Policy names a business rule. Dependency injection is how tests replace clocks and stores.

Start from Protected Variations and SOLID. Patterns are how those ideas show up as types.

What interviews reward

Name one or two extension points, then write Java

State the pain in plain language. Name the family. Name at most two patterns. Show where a new type plugs in. Then write the interface and one implementation. That is stronger than reciting all 23 names.