ATM System
What is the ATM System Problem?
Section titled “What is the ATM System Problem?”Design an ATM (Automated Teller Machine) system that allows users to perform basic banking transactions such as checking balance, withdrawing cash, and depositing cash. The system should handle user authentication, communicate with the bank’s main system, and support concurrent transactions while maintaining data consistency.
In this problem, you’ll design a system that coordinates between a local terminal and a remote bank server, handling hardware constraints like cash denominations and software challenges like race conditions in account balances.
Problem Overview
Section titled “Problem Overview”Design a secure Automated Teller Machine that authenticates users, processes various banking transactions, and dispenses physical cash based on inventory.
Core Requirements
Section titled “Core Requirements”Functional Requirements:
- Transactions: Support basic actions: checking account balance, withdrawing cash, and depositing cash.
- Authentication: Verify users via ATM card insertion and 4-6 digit PIN entry.
- Bank Communication: Securely communicate with the bank’s main system to verify accounts and process transactions.
- Cash Dispenser: Dispense requested amounts using multiple note denominations.
- Concurrency: Ensure correct behavior when multiple users or transactions happen simultaneously for the same account.
- Validation: Check for sufficient funds before processing any withdrawal request.
- Denomination Logic: Handle cases where the exact amount cannot be dispensed due to available note mix.
Non-Functional Requirements:
- Object-Oriented Design: Clear separation of concerns with well-defined roles for each class.
- Modularity: Easy to add future enhancements like new transaction types or authentication methods.
- Thread Safety: Balance updates and transaction processing must be safe from race conditions.
- State Management: Maintain a clear state flow from idle to card insertion, authentication, and completion.
- Reliability: Core transaction logic should be robust, testable, and maintainable over time.
What’s Expected?
Section titled “What’s Expected?”1. System Architecture
Section titled “1. System Architecture”The ATM acts as a client that interacts with a secure BankServer API.
2. Key Classes to Design
Section titled “2. Key Classes to Design”classDiagram
class ATM {
-ATMState currentState
-CashDispenser dispenser
-BankService bankLink
+insertCard(card)
+authenticate(pin)
+performTransaction(txn)
}
class ATMState {
<<interface>>
+handleAction()
}
class CashDispenser {
-Map~Note, Qty~ inventory
+dispense(amount)
}
class Account {
-long balance
+debit(amount)
+credit(amount)
}
ATM --> ATMState
ATM --> CashDispenser
Account "1" -- "many" Transaction
System Flow
Section titled “System Flow”Withdrawal Flow (State Transitions)
Section titled “Withdrawal Flow (State Transitions)”Key Design Challenges
Section titled “Key Design Challenges”1. Managing the Cash Mix
Section titled “1. Managing the Cash Mix”If a user wants $180, the machine should ideally give 1x$100, 1x$50, 1x$20, and 1x$10.
Solution: Use the Chain of Responsibility Pattern. Create handlers for each denomination (HundredHandler, FiftyHandler, etc.). Each handler calculates how many notes of its type it can provide and passes the remainder to the next handler in the chain.
2. Ensuring Transaction Atomicity
Section titled “2. Ensuring Transaction Atomicity”What if the bank debits the account but the ATM hardware jams and fails to dispense cash?
Solution: Use a Two-Phase Commit logic. The bank “holds” the funds, the ATM dispenses the cash, and only after the hardware confirms successful dispensing does the ATM send a “commit” message to the bank to finalize the debit.
3. Concurrency and “Double Spending”
Section titled “3. Concurrency and “Double Spending””A user might try to withdraw their entire balance from two different ATMs at the exact same time.
Solution: Implement Pessimistic Locking on the account record at the database level. When one ATM initiates a transaction, the server locks that account until the transaction is complete, forcing the second ATM to wait.
What You’ll Learn
Section titled “What You’ll Learn”By solving this problem, you’ll master:
- ✅ State Pattern - Managing complex, multi-step lifecycles.
- ✅ Chain of Responsibility - Implementing greedy algorithms for resource allocation.
- ✅ Concurrency Control - Using locking mechanisms to prevent data corruption.
- ✅ Secure System Design - Coordinating client-server interactions in a high-stakes environment.
View Complete Solution & Practice
Section titled “View Complete Solution & Practice”Ready to see the full implementation? Open the interactive playground to access:
- 🎯 Step-by-step guidance through the 8-step LLD approach
- 📊 Interactive UML builder to visualize your design
- 💻 Complete Code Solutions in Python, Java, C++, TypeScript, JavaScript, C#
- 🤖 AI-powered review of your design and code
Related Problems
Section titled “Related Problems”After mastering the ATM System, try these similar problems:
- Vending Machine - Simpler state but similar inventory logic.
- Payment Processor - Focus on API design and third-party integration.
- Task Scheduler - Handling concurrent execution and prioritization.