Low-Level Design Tutorial 0/42 lessons ~6 min read Lesson 33

    ATM Machine Design

    ATM LLD models card authentication, PIN validation, cash dispensing, balance inquiry, and transaction logging — often coordinated with a remote BankHost abstraction.

    Course progress0%
    Focus
    9 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    ATM LLD models card authentication, PIN validation, cash dispensing, balance inquiry, and transaction logging — often coordinated with a remote BankHost abstraction.

    Split hardware interfaces (CardReader, CashDispenser, Printer) from AtmService orchestration. State diagram for session: idle → authenticated → transaction → idle.

    Discuss rollback when dispense fails after debit.

    Understanding the topic

    Key concepts

    • Components: ATM, CardReader, CashDispenser, Keypad, Screen, BankHost.
    • Session after successful PIN.
    • Operations: withdraw, deposit, balance, transfer.
    • Transaction log for audit.
    • Hardware failure compensation (rollback credit).
    • Daily withdrawal limits on account.
    text
    classDiagram
    class ATM {
    +withdraw(amount)
    +deposit(amount)
    }
    class CashDispenser
    class CardReader
    ATM --> CashDispenser
    ATM --> CardReader

    Step-by-step explanation

    1. Insert card; CardReader reads token.
    2. Validate PIN with BankHost.
    3. User selects operation and amount.
    4. AtmService debits/credits via BankHost.
    5. CashDispenser dispenses on withdraw.
    6. Print receipt; eject card; end session.

    Informative example

    ATM with hardware abstractions and compensating transaction on dispense failure:

    java
    public interface BankHost {
    Optional<Account> authenticate(String cardToken, String pin);
    boolean debit(Account account, Money amount);
    void credit(Account account, Money amount);
    }
    public interface CashDispenser {
    boolean dispense(Money amount);
    }
    public final class AtmService {
    private final BankHost bank;
    private final CashDispenser dispenser;
    private final List<Transaction> log = new ArrayList<>();
    public AtmService(BankHost bank, CashDispenser dispenser) {
    this.bank = bank;
    this.dispenser = dispenser;
    }
    public Result withdraw(Account account, Money amount) {
    if (amount.isZero()) return Result.failed("invalid amount");
    if (!bank.debit(account, amount)) return Result.failed("insufficient funds");
    if (!dispenser.dispense(amount)) {
    bank.credit(account, amount);
    return Result.failed("dispenser jam");
    }
    log.add(Transaction.withdraw(account.id(), amount));
    return Result.ok();
    }
    }
    public record Account(String id, Money balance) {}
    public record Transaction(String accountId, Money amount, Instant at) {
    static Transaction withdraw(String accountId, Money amount) {
    return new Transaction(accountId, amount, Instant.now());
    }
    }

    AtmController handles UI flow; AtmService owns transactional integrity.

    Real-world use

    Real-world applications

    • Hardware abstraction LLD question.
    • Compensating transaction pattern practice.
    • State machine for session lifecycle.

    Best practices

    • DIP for all hardware and bank connections.
    • Rollback on partial failure.
    • Never store PIN — validate remotely or hash.
    • Idempotent transaction ids for retry.
    • Separate read-only balance from withdraw path.

    Common mistakes

    • Monolithic ATM class with pin + cash + sql.
    • No rollback when dispense fails.
    • Storing plaintext PIN on card model.
    • Skipping transaction audit log.

    Advanced interview questions

    Q1BeginnerMain ATM classes?
    AtmController, AtmService, CardReader, CashDispenser, BankHost, Account.
    Q2BeginnerDispense fails after debit?
    Credit account back — compensating transaction.
    Q3IntermediateHow model deposit?
    Accept envelope/cash module confirms; credit via BankHost after verification.
    Q4IntermediateConcurrent access same account?
    BankHost serializes account updates or uses optimistic locking.
    Q5AdvancedDesign ATM chain with shared cash replenishment.
    CashInventory per ATM; CentralOps service aggregates levels; Dispenser pulls from inventory.

    Summary

    ATM splits UI, service, hardware, bank host. Compensating credit on dispense failure. Session state machine for authenticated flows. Transaction log for audit trail. DIP enables testing without real hardware.

    Ready to mark this lesson complete?Track your journey across the entire course.