ATM Machine
ATM bhi State machine hai — IDLE → CARD_INSERTED → AUTHENTICATED → TRANSACTION → DISPENSING. Vending machine se farak ye hai ki yahan AUTHENTICATION aur ATOMICITY critical hain: paise account se katne chahiye SIRF tab jab note actually nikal jaayein.
Cash dispensing ke liye Chain of Responsibility pattern classic answer hai — ₹2000 handler pehle koshish karta hai, bacha hua amount ₹500 handler ko, phir ₹100 handler ko. Ye naye denomination add karna trivial bana deta hai aur interviewer ko pattern ka natural use dikhta hai.
abstract class CashDispenser {
private final int denomination;
private CashDispenser next;
void dispense(int amount) {
int notes = amount / denomination;
int remaining = amount % denomination;
if (notes > 0) inventory.deduct(denomination, notes);
if (remaining > 0 && next != null) next.dispense(remaining);
else if (remaining > 0) throw new InsufficientNotesException();
}
}
// Chain: 2000 -> 500 -> 200 -> 100- States: IDLE → CARD_INSERTED → AUTHENTICATED → TRANSACTION → DISPENSING
- Cash dispensing ke liye Chain of Responsibility — denomination chain
- Debit aur dispense atomic rakho, failure par rollback
ATM ka sabse critical invariant hai: paisa account se katna aur note nikalna EK SAATH hona chahiye. Agar debit ho gaya par note atak gaya, to customer ka paisa gaya aur wo sabse mehnga bug hai.
Practical approach: pehle amount HOLD karo (reserve), phir dispense karo, dispense confirm hone par hold ko actual debit banao. Dispense fail hone par hold release kar do. Ye two-phase approach hi real ATMs use karte hain.
void withdraw(Account acc, int amount) {
String holdId = ledger.hold(acc, amount); // 1. reserve
try {
dispenser.dispense(amount); // 2. physical
ledger.commit(holdId); // 3. confirm
} catch (DispenseException e) {
ledger.release(holdId); // rollback
throw e;
}
}PIN kabhi plain text mein store nahi hota — hash (salt ke saath) hota hai. Teen galat attempt par card block. Session ka timeout hona chahiye: user card daalkar chala jaaye to machine apne aap IDLE par wapas aa jaaye aur card eject kar de.
Ye batana ki "card retain kar lena ya eject karna" ek business decision hai, aur dono ke apne trade-off hain — ye domain thinking dikhata hai.