LLD Case Studies
Design Vending Machine
Design an automated vending machine system using the State Design Pattern to manage transactions, inventory, and payment changes.
Last Updated: June 26, 2026
•
23 min read
1. Requirements & Assumptions
Functional Requirements
- The vending machine holds multiple product slots, each identified by a unique code (e.g., A1, B2).
- Accepts coins (e.g., $0.10, $0.25, $1.00) and bills ($1.00, $5.00).
- Supports state transitions: Idle, HasMoney, Dispensing, OutOfStock.
- Validates inserted coins/bills, select products, and returns change.
- Allows users to cancel the transaction at any time before dispensing to receive a full refund.
Non-Functional Requirements
- Transactional Integrity: The machine must not dispense a product unless the payment is fully validated, and must return the correct change.
- Modularity: Adding new states or product codes should be easy.
Assumptions
- The machine runs as an embedded system with a single execution loop.
- The coin inventory for returning change is finite.
2. Entities, Responsibilities & Relationships
- VendingMachine (Context): Holds active states, balance, and inventory references. Delegates operations to the current state object.
- State (Interface): Declares methods for insertion, selection, cancel, and dispense.
- IdleState, HasMoneyState, DispensingState: Concrete states implementing state-specific behaviors.
- Inventory: Tracks products and quantities available in each slot.
- CoinBasket: Manages internal coin counts to calculate and dispense change.
3. Diagrams
UML Class Diagram
State Transition Diagram
4. Design Decisions
- State Pattern: Eliminates complex conditional chains (
if-elseorswitchblocks) by representing each machine state as a separate class. - Atomic Dispensing: Decrementing inventory and calculating change are executed inside a single state transition, ensuring data consistency.
5. Step-by-Step Implementation
- Define the
Productentity with name and price fields. - Implement
Inventoryto manage product mappings and stock quantities. - Create the polymorphic
Stateinterface. - Implement concrete states:
IdleState,HasMoneyState, andDispensingState. - Create the
VendingMachinecontext class to manage active states, balance, and inventory.
6. Complete Code
7. Test Cases & Verification
- Test Case 1: Insufficient Balance: Insert $1.00 for a $1.50 Soda. Verify that product selection is rejected and the balance remains at $1.00.
- Test Case 2: Out of Stock Selection: Select a product slot with 0 quantity. Verify that the request is rejected and money is retained in the machine.
- Test Case 3: Cancel Refund: Insert $2.00 and hit cancel. Verify that the machine returns $2.00 and transitions back to the Idle state.
8. Scalability & SOLID Improvements
- SOLID - Single Responsibility Principle: The
Inventoryclass handles product mapping and stock tracking, while states handle logical transition rules. This keeps the classes small and cohesive. - Extensibility: Adding a payment terminal (e.g. card/NFC payments) is simple. We can introduce a
CardPaymentStatethat implements theStateinterface, extending the machine's capabilities without modifying existing state classes.
9. Production Considerations
- Finite Coin Reserve: Exit logic should verify if the machine's internal coin cache has enough coins to return change. If not, the machine must display a warning (e.g. "Exact Change Only") and reject transactions that require change.
- Hardware API Interfacing: In a physical machine, state changes are tied to hardware sensors (e.g., coin drop gates, laser sensors to verify product dispensing). We can use the Observer Pattern to listen to these sensor interrupts.
10. Next Lesson Preview
In the next case study, we will design a Rate Limiter. We will study the Token Bucket and Sliding Window algorithms, thread-safety, and concurrent request filtering!
Related Topics
- Design Parking LotDesign a multi-level parking lot system with variable pricing strategies, support for different vehicle types, and concurrent allocation.
- Design Rate LimiterDesign a high-performance, thread-safe API rate limiter using the Token Bucket algorithm to filter concurrent requests.
- Design Elevator SystemDesign a multi-elevator controller system supporting direction-based dispatch algorithms, internal/external requests, and floor synchronization.