Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
Chaturmind
← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
HomeLearnSystem DesignLow-Level Design & Design PatternsMachine Coding Exercises
✓ FreeIntermediate· 7 min read

Vending Machine Design

The canonical State pattern interview question — modeling a vending machine as Idle/HasMoney/Dispensing/OutOfStock states, explicitly.

Published September 23, 2026


Vending Machine Design

If one machine-coding prompt exists specifically to test State Pattern, it's this one — a vending machine's behavior is entirely determined by which state it's in, making it close to the cleanest real-world example of the pattern.

Core classes

class Product {
    final String code;
    final double price;
    int quantity;
}

class Inventory {
    private final Map<String, Product> products = new HashMap<>();
    boolean hasStock(String code) { return products.containsKey(code) && products.get(code).quantity > 0; }
    void dispense(String code) { products.get(code).quantity--; }
}

interface CoinAcceptor { double insertCoin(Coin coin); } // returns running total inserted

Modeling as a state machine

IDLE ──(product selected)──▶ HAS_MONEY_PENDING (waiting for sufficient payment)
HAS_MONEY_PENDING ──(enough money inserted)──▶ DISPENSING
DISPENSING ──(product released)──▶ IDLE (or OUT_OF_STOCK if that was the last unit)
any state ──(selected product has zero stock)──▶ OUT_OF_STOCK (rejects selection, returns to IDLE)

Implementing with State pattern, explicitly

interface VendingMachineState {
    void selectProduct(VendingMachine machine, String code);
    void insertCoin(VendingMachine machine, Coin coin);
    void dispense(VendingMachine machine);
}

class IdleState implements VendingMachineState {
    public void selectProduct(VendingMachine machine, String code) {
        if (!machine.getInventory().hasStock(code)) {
            machine.setState(new OutOfStockState());
            return;
        }
        machine.setSelectedProduct(code);
        machine.setState(new HasMoneyPendingState());
    }
    public void insertCoin(VendingMachine machine, Coin coin) { /* no-op or reject — no product selected yet */ }
    public void dispense(VendingMachine machine) { /* no-op — nothing to dispense */ }
}

class HasMoneyPendingState implements VendingMachineState {
    public void selectProduct(VendingMachine machine, String code) { /* already mid-transaction — ignore or reject */ }
    public void insertCoin(VendingMachine machine, Coin coin) {
        double total = machine.addPayment(coin.getValue());
        if (total >= machine.getSelectedProductPrice()) {
            machine.setState(new DispensingState());
        }
    }
    public void dispense(VendingMachine machine) { /* not ready yet */ }
}

class DispensingState implements VendingMachineState {
    public void selectProduct(VendingMachine machine, String code) { /* mid-dispense — ignore */ }
    public void insertCoin(VendingMachine machine, Coin coin) { machine.refund(coin); } // reject further coins mid-dispense
    public void dispense(VendingMachine machine) {
        machine.getInventory().dispense(machine.getSelectedProduct());
        machine.returnChange();
        machine.setState(machine.getInventory().hasStock(machine.getSelectedProduct()) ? new IdleState() : new OutOfStockState());
    }
}

class OutOfStockState implements VendingMachineState {
    public void selectProduct(VendingMachine machine, String code) {
        if (machine.getInventory().hasStock(code)) machine.setState(new IdleState()); // a DIFFERENT product might still be in stock
    }
    public void insertCoin(VendingMachine machine, Coin coin) { machine.refund(coin); }
    public void dispense(VendingMachine machine) { /* nothing to dispense */ }
}
class VendingMachine {
    private VendingMachineState state = new IdleState();
    void setState(VendingMachineState state) { this.state = state; }
    void selectProduct(String code) { state.selectProduct(this, code); } // every public method delegates identically
    void insertCoin(Coin coin) { state.insertCoin(this, coin); }
    void dispenseProduct() { state.dispense(this); }
}

The reason this is the canonical State pattern question, rather than just an example: every one of VendingMachine's public methods has genuinely different, non-trivial behavior in every state (inserting a coin does nothing in IdleState, accumulates toward payment in HasMoneyPendingState, and triggers a refund in DispensingState/OutOfStockState) — this is exactly the profile State Pattern's own "when it earns its complexity" guidance describes, unlike the traffic-light example where an enum+switch would have been simpler.

Follow-up questions this topic invites — and their answers

Q: Why does OutOfStockState.selectProduct() check hasStock() for the newly-selected code, rather than just staying OutOfStock forever? A: Out-of-stock is per-product, not a global machine condition — a machine that's out of one item can still sell a different item, so the state needs to re-evaluate stock for whatever the new selection is, not assume the machine-wide state should persist.

Q: How would you handle a coin insertion that overshoots the product price? A: DispensingState (or a transition trigger just before it) needs to compute and dispense change — machine.returnChange() in the dispense() implementation is where that logic would live, calculating (total inserted - product price) and dispensing the appropriate coins/refusing if exact change isn't available.

Q: What's a concurrency concern for a real vending machine handling this design? A: A physical vending machine typically serves one transaction at a time by hardware nature, so concurrency is less of an issue than, say, Parking Lot's concurrent spot claims — but a software simulation or a networked/cashless variant would need the same kind of per-transaction locking discussed in Parking Lot — Implementation if multiple insertCoin/selectProduct calls could race.

Q: Could this same state machine structure model a different real-world system? A: Yes — any system where behavior is genuinely gated by a multi-step transaction with distinct in-progress states (a self-checkout kiosk, an elevator's door-open/moving states from Elevator System, an order's Pending/Paid/Shipped lifecycle) follows the identical State pattern shape.

Previous

Chess Engine Design

Next

ATM System Design

AI Tutor

Lesson: Vending Machine Design

Quick actions

AI responses can be inaccurate. Verify critical information.