CMD Guide
HomeOO & Low-Level DesignDesign Patterns Overview

Introduction (3)

Behavioral Patterns

Behavioral patterns assign responsibilities and shape how objects communicate. Most production bugs live in interaction, not in isolated classes — these patterns give explicit structures for that interaction.

Behavioral patterns in one example

Behavioral patterns manage how objects communicate and vary. Two of the most common are Observer and Strategy; they share a similar shape (a context holds a reference to an interface with concrete implementations) but have different intent.

Observer is about notifying many subscribers. A NewsFeed subject pushes new posts to every registered observer, which can react independently.

interface Observer {
    void update(String post);
}

class NewsFeed {
    private final List<Observer> observers = new ArrayList<>();

    void subscribe(Observer o) { observers.add(o); }

    void publish(String post) {
        for (Observer o : observers) o.update(post);
    }
}

// Usage
NewsFeed feed = new NewsFeed();
feed.subscribe(new EmailNotifier());
feed.subscribe(new PushNotifier());
feed.publish("New course available!");

Strategy is about swapping one algorithm. A Checkout delegates shipping-cost calculation to an interchangeable strategy instead of growing an if/else chain.

interface ShippingCost {
    double cost(Order order);
}

class FlatRate implements ShippingCost {
    public double cost(Order o) { return 5.0; }
}

class ByWeight implements ShippingCost {
    public double cost(Order o) { return o.weightKg() * 1.20; }
}

class Checkout {
    private final ShippingCost strategy;
    Checkout(ShippingCost strategy) { this.strategy = strategy; }

    double total(Order o) { return o.subtotal() + strategy.cost(o); }
}

// Usage
Checkout c = new Checkout(new ByWeight());

The discriminator matters: Observer notifies many subscribers; Strategy swaps one algorithm; Command encapsulates a request so it can be queued, logged, or undone.

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 an Observer" and have everyone understand the forces, structure, and consequences.

Behavioral patterns matter because most production bugs come from interaction, not from isolated classes. Two classes that each look correct can still produce race conditions, notification storms, or tangled if/else logic when they communicate. Behavioral patterns give explicit structures for that communication.

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 objects need to react to one state change.)
  2. Structure. What classes collaborate and what are their responsibilities? (Example: Subject holds observers; observers implement a common interface.)
  3. Consequences. What do you gain and what do you pay? (Example: loose coupling, but risk of notification cascades.)

If a pattern description skips any of the three, you do not have enough to apply it correctly.

Pattern-selection flowchart

Does one object need to notify many dependents?
        | yes
        v
   Use Observer
        | no
        v
Can the algorithm vary at runtime?
        | yes
        v
   Use Strategy
        | no
        v
Must requests be queued, logged, or undone?
        | yes
        v
   Use Command
        | no
        v
Does behavior change dramatically based on state?
        | yes
        v
   Use State
        | no
        v
Is the algorithm skeleton fixed but steps vary?
        | yes
        v
   Use Template Method
        | no
        v
   Keep plain methods or lambdas

Types of Behavioral Design Patterns

Types of Behavioral Patterns
Types of Behavioral Patterns
PatternIntroduction
Chain of ResponsibilityDelegates commands to a chain of processing objects.
CommandEncapsulates a command request as an object.
InterpreterImplements a specialized language interpretation.
IteratorSequentially accesses elements of a collection.
MediatorCentralizes complex communications and control between related objects.
MementoCaptures and externalizes an object's internal state.
ObserverMaintains consistency between loosely coupled objects.
StateAllows an object to change its behavior when its internal state changes.
StrategyEnables an algorithm's behavior to be selected at runtime.
Template MethodDefines the skeleton of an algorithm in the superclass but lets subclasses override specific steps.
VisitorDefines a new operation to a class without change.

When a behavioral pattern is overkill

Behavioral patterns buy flexibility at the cost of indirection and more classes. In modern languages with first-class functions, some patterns shrink: Strategy becomes a lambda or comparator, and Iterator is built into for-each loops. Applying the full class hierarchy in those cases is ceremony. Reach for the pattern when you need its extra machinery — queuing and undo for Command, multi-subscriber notification for Observer, self-driven state transitions for State — otherwise a plain function or loop is usually clearer.

Self-check (behavioral)

  1. State vs Strategy. Both look like a context holding a strategy-like object. Strategy: the client (or context) chooses an algorithm; algorithms are usually independent of each other. State: the object transitions itself between states; each state may know the next. When would shipping-cost calculation be Strategy but order lifecycle be State?
  2. Command vs Strategy. Strategy swaps how a calculation is done for an immediate call. Command encapsulates a request as an object so it can be queued, logged, undone, or executed later. When is "just call the method" enough, and when do you need Command?
  3. Observer memory leak. Subject holds strong references to observers. A forgotten unsubscribe keeps the observer (and everything it references) alive. What lifecycle hook do you need in a long-lived subject (event bus, UI widget, domain aggregate)? Prefer weak refs or explicit unsubscribe; at process boundaries prefer a durable event bus with consumer groups, not in-process Observer.

Two more discriminators interviewers reach for

Failure modes to name in a design round

The judgment that separates strong candidates is knowing how these patterns fail in production: a synchronous Observer notify loop is only as fast as its slowest listener — one slow or throwing subscriber stalls or breaks the whole publish, so isolate failures and consider an async queue at scale. An Observer whose subject holds strong references leaks memory on a forgotten unsubscribe (watch listener_count growth). A Command bus without idempotency double-applies on retry. Alert on handler error rate; treat "everything is an event" as a smell — local sequential logic should stay a direct call, events are for cross-boundary reactions.

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

Stuck on Introduction (3)? 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 (3)** (OO & Low-Level Design) and want to truly understand it. Explain Introduction (3) 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 (3)** 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 (3)** 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 (3)** 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