What design patterns did you use in the ATM design and why?
Fast recall
Quick revision
Core answer
Whether you can articulate why each pattern fits the problem—not just name-dropping but explaining the design trade-off each pattern solves
Listing patterns without justification or using patterns unnecessarily (e.g., Factory when direct instantiation is simpler)
Mention a pattern you deliberately avoided and why (e.g., didn't use Observer because ATM state changes are synchronous, not event-driven)
Interview-ready guide
Interview answer
I would start with State because an ATM has a clear lifecycle: idle, card inserted, authenticated, and processing a transaction. Each state accepts only its legal actions and chooses the next state, so authentication checks are not copied into every method.
Strategy fits rules that really vary, such as withdrawal policies supplied by different account products. A transaction can be represented as a Command when it needs its own id, status, audit record, retry, or reversal path. The ATM acts as a Facade over the bank gateway and device adapters, giving the state objects a small set of operations instead of exposing hardware details.
I would not use Singleton merely because the diagram represents one physical ATM. Application configuration can create one aggregate per machine, and Singleton would only limit objects in one JVM. The pattern choice should follow the required behaviour: if there is no varying policy or auditable command lifecycle, a direct method may be clearer.
What design patterns did you use in the ATM design and why
Direct Answer
Key patterns: (1) State pattern for clean state machine (Idle, CardInserted, Authenticated, DispensingCash states), (2) Singleton for ATM controller (one instance per machine), (3) Strategy pattern for account types (Savings vs Checking have different withdrawal limits), (4) Command pattern for each ATM action (enables undo and audit logging), (5) Facade pattern where ATM class hides CashDispenser, CardReader, BankServer complexity from user interaction layer.
Deep Dive & Architecture
State controls valid actions
The ATM changes through clear phases such as idle, card inserted, authenticated, and dispensing. An ATMState object owns the actions allowed in one phase, so a withdrawal cannot happen before authentication and a second card cannot be inserted during a transaction.
Strategy and Command isolate changing behaviour
A WithdrawalPolicy strategy can apply different limits to savings and checking accounts without adding account-type conditionals to the ATM. A transaction command represents one requested action, such as withdraw or balance enquiry, and gives the system one place to record its status and audit data.
Facade keeps the hardware boundary small
The ATM facade coordinates the card reader, bank gateway, receipt printer, and cash dispenser behind a small set of operations. For a ₹500 withdrawal, the authenticated state accepts the request, the policy validates it, a withdrawal command calls the bank, and the facade dispenses cash only after approval. Each pattern has one job; it should be removed if that job does not exist in the requirements.
Code Example
interface WithdrawalPolicy {
Decision check(WithdrawalRequest request, AccountSnapshot account);
}
record WithdrawalCommand(UUID id, Money amount, TransactionStatus status) {}
class ATM { // facade over external bank and machine hardware
private final BankGateway bank;
private final CashDispenser cash;
private ATMState state;
ATM(BankGateway bank, CashDispenser cash) {
this.bank = bank;
this.cash = cash;
this.state = new IdleState();
}
void transitionTo(ATMState next) { state = next; }
}
Common Mistakes & Pitfalls
- Pattern-name lists — connect each pattern to a concrete lifecycle or variation.
- Singleton as consistency — it cannot protect state across processes or machines.
- Command without a command lifecycle — a normal method is simpler when audit, retry, or reversal is not required.
- Facade that leaks its subsystems — callers should not bypass it and manipulate the dispenser directly.
Check your understanding
Answer these without looking back at the article.
- Design an ATM system. What are the key classes and interactions?
- How do you model the State pattern for an ATM?
- How does the cash dispensing algorithm work in your ATM design?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.