About Us Contact Us Write for Us Advertise
Home > System Design > Low-Level Design > Design a Vending Machine (Low-Level Design)
System Design › Low-Level Design

Design a Vending Machine (Low-Level Design)

Design a vending machine in an LLD interview — the textbook State pattern problem. States (Idle, HasMoney, Dispensing, OutOfStock), inventory, the change algorithm, classes, UML, and key decisions.

Shiv Pandey
Shiv Pandey
Oct 26, 2026 | 61 views
Design a Vending Machine (Low-Level Design)

🟠 Low-Level Design · Case Study · Senior

"Design a vending machine" is the textbook problem for the State pattern — because a vending machine is a state machine. It behaves completely differently depending on whether it's idle, holding your money, or dispensing. Model that cleanly and the whole design falls into place. Let's build it.

The approach in one line: model the machine as a State machine — Idle → HasMoney → Dispensing → back to Idle — where each state class defines what the actions (select, insert money, dispense) do, plus an inventory of products and a change calculator.

Step 1 — Requirements

  • Functional: user selects a product, inserts money (coins/notes), machine dispenses if enough money and in stock, returns change; refund if cancelled; admin can restock.
  • Non-functional: never dispense without payment, never give wrong change, handle out-of-stock and insufficient funds gracefully.

Step 2 — The classes

  • VendingMachine — the context; holds the current state, inventory, and inserted balance.
  • State (interface) with concrete states: IdleState, HasMoneyState, DispensingState, OutOfStockState — each implements the machine's actions.
  • Product and Inventory (product → count, price).
  • Coin / Note enums for denominations; a change calculator.

Step 3 — The state machine (the heart)

Idle Has Money Dispensing Out of Stock insert $ enough+select dispensed + change → Idle
interface State { void insertMoney(int amt); void selectProduct(String id); void dispense(); }

class IdleState implements State {
    private final VendingMachine m;
    public void insertMoney(int amt){ m.addBalance(amt); m.setState(m.hasMoney); }
    public void selectProduct(String id){ System.out.println("Insert money first"); }
    public void dispense(){ /* nothing */ }
}
class HasMoneyState implements State {
    public void selectProduct(String id){
        if (m.inStock(id) && m.balance() >= m.price(id)) m.setState(m.dispensing);
        else System.out.println("Out of stock or insufficient funds");
    }
    // …
}
class VendingMachine {                 // the context
    State idle, hasMoney, dispensing;  // one instance each
    private State state = idle;
    void setState(State s){ this.state = s; }
    void insertMoney(int a){ state.insertMoney(a); }   // delegate to state
    void selectProduct(String id){ state.selectProduct(id); }
}

Each state enforces its own rules — you can't select a product in Idle, can't insert money mid-dispense. The invalid transitions simply don't exist, which is exactly what makes the State pattern shine here.

Step 4 — The tricky bit: change

🔴 Returning change is a mini algorithm: given an amount, dispense the fewest coins/notes from available denominations (a greedy approach for standard denominations). Edge case interviewers love: what if you can't make exact change? — refuse the sale and refund, or warn "exact change only." Calling this out shows thoroughness.

Step 5 — Other decisions

🟠 Keep inventory as a map of product → (price, count); decrement on dispense and flip to OutOfStock when a slot empties. Handle cancel (refund the balance and return to Idle). If it's multi-threaded (real machines aren't, but interviewers ask), guard the balance/inventory. Enums for denominations avoid magic numbers.

The interview-ready walkthrough

"A vending machine is a State machine, so I'd model states — Idle, HasMoney, Dispensing, OutOfStock — each a class implementing the actions (insert money, select, dispense), with the VendingMachine context delegating to the current state and holding inventory + balance. Invalid transitions (selecting before paying) are impossible by design. I'd keep inventory as product→(price,count), compute change greedily and handle the can't-make-exact-change case, and support cancel/refund. Enums for denominations." That's the State pattern applied crisply — the whole point of the question."

What to read next

← Design an elevator system · Design BookMyShow (LLD) →

Related Articles

Design a Food Delivery App (Low-Level Design)
System Design › Low-Level Design

Design a Food Delivery App (Low-Level Design)

Design a Meeting Scheduler (Low-Level Design)
System Design › Low-Level Design

Design a Meeting Scheduler (Low-Level Design)

Design Snake and Ladder (Low-Level Design)
System Design › Low-Level Design

Design Snake and Ladder (Low-Level Design)

Design Chess (Low-Level Design)
System Design › Low-Level Design

Design Chess (Low-Level Design)