How do you model the State pattern for an ATM?
Fast recall
Quick revision
Core answer
Deep understanding of State pattern mechanics—how state objects collaborate and transition control flow
Using enum or switch statements instead of polymorphic state objects, which creates a maintenance nightmare as states grow
Explain that each state object can hold state-specific data (like failed PIN attempts in AuthenticatedState) and demonstrate setState() call with concrete state names
Interview-ready guide
Interview answer
The State pattern lets an object change its behaviour as its internal state changes, almost as if it switched class. For the ATM I'd define an ATMState interface that lists every operation — insertCard, enterPin, withdraw, and so on. Then I create one concrete class per phase: IdleState, CardInsertedState, AuthenticatedState, DispensingState. The ATM object holds a reference to the current state and delegates every user action to it. So ATM.withdraw just calls currentState.withdraw.
The elegance is that each state only implements the transitions that make sense for it. In IdleState, withdraw throws an IllegalStateException because there's no card. In AuthenticatedState, withdraw actually dispenses cash and then transitions back to IdleState by calling atm.setState. The transition logic lives inside the states themselves.
Compare that to the naive version, which uses boolean flags like cardIn and authenticated, and every single method starts with the same pile of if-checks. When you add a new phase, you have to touch every method. With the State pattern, a new phase is just a new class, which is the Open/Closed Principle.
The mistakes I'd watch for: forgetting to actually transition — if a state handler doesn't call setState, the machine gets stuck — and putting business logic in the ATM controller instead of the states. The controller should be thin and just delegate; the rules belong in the state classes.
How do you model the State pattern for an ATM
Direct Answer
The State pattern uses an ATMState interface defining all operations (insertCard, enterPIN, withdraw, etc.). Each concrete state class implements only valid transitions for that phase; invalid operations throw IllegalStateException or do nothing. The ATM object holds a currentState reference and delegates every user action to currentState.operation(), and states call atm.setState() to transition.
Deep Dive & Architecture
The current state owns the valid operations
ATMState defines actions such as insertCard, enterPin, withdraw, cancel, and timeout. Concrete states implement only what makes sense at that point. IdleState.insertCard() creates a session and moves to CardInsertedState; CardInsertedState.enterPin() either records a failed attempt or moves to AuthenticatedState.
Transitions are part of the model
A successful withdrawal can move Authenticated → Dispensing → Authenticated for another action, while cancel or timeout returns any active state to Idle after clearing session data. Invalid transitions return a clear error and leave the state unchanged. This makes the allowed paths visible and testable instead of spreading checks such as if (authenticated) across every method.
State objects and delegated services
The state decides whether an action is allowed and what comes next. It delegates PIN verification to the bank gateway and note handling to the dispenser. Tests can then assert a transition table—for example, Idle + withdraw is rejected, while Authenticated + withdraw calls authorization and enters Dispensing only when it succeeds.
Common Mistakes & Pitfalls
- Boolean flag soup (
cardIn,authed) — the smell the State pattern removes. - States that don't transition — each handler must call
atm.setState(...)or the machine stalls. - Putting business logic in the controller — the
ATMshould delegate; the rules belong in the state classes. - Silently ignoring invalid actions — throw instead, so bugs surface immediately.
Check your understanding
Answer these without looking back at the article.
- Design an ATM system. What are the key classes and interactions?
- How does the cash dispensing algorithm work in your ATM design?
- What security considerations are important in your ATM design?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.