SwadhyAI Notes

All Low-Level Design notes

Behavioral · Gang of Four

Chain of Responsibility

Chain of Responsibility is a behavioral pattern that passes a request along a list of handlers. Each handler either handles the request or forwards it. The caller does not know which handler will answer.

Example: an ATM withdrawal needs several checks — card valid, PIN correct, balance enough, fraud screen. A 200-line withdraw() with nested ifs is hard to extend. A chain of handlers keeps each check in its own class.

The interview question

Can I add or reorder a check without opening the 200-line method?

  1. 1Name the request (Withdrawal).
  2. 2Give every handler the same door.
  3. 3Link with setNext, not concrete names.
  4. 4Stop on failure; cash moves last.

Request walk

The line, left to right

Client talks to Auth. Auth talks to Balance. Balance talks to Limit. Limit talks to Fraud. Nobody in the ATM class names FraudHandler. That is the point: a new KYC check is a new class plus one .

Auth

reject if card is fake

PIN

reject if PIN is wrong

Balance

reject if funds are short

Fraud

stop if the pattern looks stolen

Dispense

only if the line said yes

What happens on a bad PIN

The walk is allowed to die early. That is how a chain differs from a of validators that all run, and from Decorator, where every wrapper still does the call and adds something.

Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
Read the diagram definition
sequenceDiagram
    participant ATM as ATM
    participant A as Auth
    participant B as Balance
    participant L as Limit
    participant F as Fraud

    ATM->>A: handle(withdrawal)
    alt card invalid
        A-->>ATM: Unauthorized
    else card ok
        A->>B: handle
        alt funds short
            B-->>ATM: InsufficientFunds
        else funds ok
            B->>L: handle
            L->>F: handle
            F-->>ATM: ok, dispense
        end
    end

Chain

Who should answer?

A member may swallow the request. Auth fails, fraud never runs. Use this for ATM checks, support-ticket routing, and HTTP .

Decorator

Wrap, then still call

Logging, metrics, and retries sit in front of an object and still invoke it. Nobody in the line is allowed to skip the real work unless that is the decorator’s job.

Template

Outline always runs

Parse, validate, persist — every step. See Template Method. If you need to insert a step without a subclass, a list of handlers is more honest.

Java: auth, then balance, then the rest

Tests inject a shorter line. The ATM never names FraudHandler. Build the line once in a factory or the composition root — the same seam validation wants when rules grow.

java
interface Handler {
  Handler setNext(Handler next);
  void handle(Withdrawal w);
}

abstract class BaseHandler implements Handler {
  private Handler next;
  public Handler setNext(Handler next) {
    this.next = next;
    return next;
  }
  public void handle(Withdrawal w) {
    if (next != null) next.handle(w);
  }
}

class AuthHandler extends BaseHandler {
  public void handle(Withdrawal w) {
    if (!w.card().isValid()) throw new Unauthorized();
    super.handle(w);
  }
}

class BalanceHandler extends BaseHandler {
  public void handle(Withdrawal w) {
    if (w.account().balance().lessThan(w.amount())) throw new InsufficientFunds();
    super.handle(w);
  }
}

// Built once, outside the ATM:
// auth.setNext(balance).setNext(limit).setNext(fraud);

ATM as the interview picture

Many ATM designs use both a State machine for “which buttons work now” and a chain for “this withdrawal is allowed.” Do not mash those into one switch.

What is the request object?

A Withdrawal (or Payment) that already holds card, PIN, amount, and account. Handlers should not reach back into the ATM for data they forgot to put on the request.

Who decides the order?

A factory or the machine-coding “wire-up” method. Handlers must not construct their successor as a concrete class. new AuthHandler(new BalanceHandler(...)) baked into AuthHandler couples the chapters.

State for the session, chain for the checks

No-card, has-card, authenticated is State. Auth then balance then fraud is Chain. The authenticated state may start the chain; the chain does not become the state machine.

Smell

A chain that is still one method

Five private methods called in order from withdraw() is not the pattern. You cannot insert a handler without editing that method. The line must be objects you can relink.

Smell

Every handler names the next concrete class

Hold a Handler next, or build the line outside. Otherwise a new KYC check still edits AuthHandler.

Nearby in LLD

Behavioral family: who handles the request, not how the object is built.