Behavioral PatternsChain of ResponsibilityMedium⏱️ ~3 min

Applying Chain of Responsibility: ATM Cash Dispenser

Domain: ATM Cash Dispensing System

When you withdraw cash from an ATM, the machine must dispense the correct amount using available bill denominations. The ATM contains cassettes with different bill types (for example, 2000, 500, 100 rupee notes). The system must calculate the optimal combination of bills to dispense.

The Chain of Responsibility pattern models this perfectly. Each handler represents a bill denomination dispenser. The withdrawal request passes through the chain, with each handler dispensing as many bills as it can, then passing the remaining amount to the next handler.

Class Design

WithdrawalRequest
- amount: int
- dispensedBills: Map<Denomination, int>
+ getAmount(): int
+ reduceAmount(value: int): void
+ recordBills(denom: Denomination, count: int): void
«interface»
BillDispenser
+ setNext(dispenser: BillDispenser): BillDispenser
+ dispense(request: WithdrawalRequest): void
TwoThousandDispenser
- nextDispenser: BillDispenser
- denomination: int = 2000
+ dispense(request): void
FiveHundredDispenser
- nextDispenser: BillDispenser
- denomination: int = 500
+ dispense(request): void
HundredDispenser
- nextDispenser: BillDispenser
- denomination: int = 100
+ dispense(request): void
ATM
- dispenserChain: BillDispenser
+ withdraw(amount: int): WithdrawalRequest

Processing Logic

Pseudocode for Concrete Dispenser:
function dispense(request):
  remainingAmount = request.getAmount()
  if remainingAmount >= this.denomination:
    billCount = remainingAmount / this.denomination
    remainingAmount = remainingAmount % this.denomination
    request.recordBills(this.denomination, billCount)
    request.reduceAmount(billCount * this.denomination)
  if remainingAmount > 0 and nextDispenser exists:
    nextDispenser.dispense(request)

Example Scenario

Withdrawal Request: 4700 rupees

First, TwoThousandDispenser processes the request. It calculates 4700 / 2000 = 2 bills with 700 remaining. It records 2 bills of 2000 denomination and reduces the request amount to 700.

Second, FiveHundredDispenser receives the remaining 700. It calculates 700 / 500 = 1 bill with 200 remaining. It records 1 bill of 500 denomination and reduces the request amount to 200.

Third, HundredDispenser receives the remaining 200. It calculates 200 / 100 = 2 bills with 0 remaining. It records 2 bills of 100 denomination and reduces the request amount to 0.

Result: 2x2000, 1x500, 2x100 (Total: 4700)

Design Benefits

Easy to Add Denominations: Adding a new bill type (for example, 200 rupee notes) requires creating a new dispenser class and inserting it into the chain. No existing dispensers need modification, following the Open/Closed Principle (OCP).

Flexible Ordering: The ATM can change the dispensing priority by reordering the chain. For example, during a shortage of large bills, the chain could start with smaller denominations.

Independent Handlers: Each dispenser has a single responsibility: dispense bills of one denomination. This makes testing and maintenance straightforward.

Interview Tip: When discussing this example, mention edge cases. What if the amount cannot be dispensed exactly (for example, 2350 with only 2000 and 500 notes available)? The last handler should check if any amount remains and throw an appropriate exception or notification if exact change is impossible.
💡 Key Takeaways
Each bill dispenser is a concrete handler responsible for one denomination
Withdrawal request passes through chain from largest to smallest denomination
Each dispenser calculates how many bills it can provide and reduces remaining amount
Chain allows easy addition of new denominations without modifying existing handlers
Pattern enables flexible reordering of denomination priority based on ATM inventory
📌 Examples
1Withdraw 4700: 2x2000 + 1x500 + 2x100 through chain of dispensers
2Add 200 rupee notes by inserting new handler between 500 and 100 dispensers
3Handle insufficient exact change by checking remaining amount at chain end
← Back to Chain of Responsibility Overview
Applying Chain of Responsibility: ATM Cash Dispenser | Chain of Responsibility - System Overflow