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
- dispensedBills: Map<Denomination, int>
+ reduceAmount(value: int): void
+ recordBills(denom: Denomination, count: int): void
+ dispense(request: WithdrawalRequest): void
- denomination: int = 2000
- denomination: int = 500
- denomination: int = 100
+ withdraw(amount: int): WithdrawalRequest
Processing Logic
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.