Design Vending Machine (LLD)
1. Requirements
-
Functional
- Display slot inventory; accept coins and notes; dispense product and change.
- Reject invalid selections when empty; refund on cancel before vend.
- Track cash box inventory for operator reconciliation.
-
Non-Functional
- Coin insertion and vending steps transactional from customer perspective.
- Extensible payment (cash now; card later via strategy).
-
Assumptions / Out of Scope
- Temperature-controlled compartments omitted unless modeled as slot metadata.
2. Core Entities
| Entity | Responsibility | Key Attributes |
|---|---|---|
| VendingMachine | Orchestrates flow | slots, paymentSession, cashInventory |
| Slot | Product holder | code, product, price, quantity |
| Product | Merchandise descriptor | name, sku |
| CoinLedger | Tracks inserted and change due | accepted denominations |
| PaymentSession | Mutable basket during purchase | insertedAmount, selectedSlot |
| Dispenser | Physical release | drop slot |
3. Class Diagram
Loading diagram…
4. State / Sequence Diagram (where relevant)
Loading diagram…
5. Design Patterns Applied
- State — Customer interaction states (
Idle,AcceptingPayment,Dispensing). State pattern. - Strategy — Payment mode cash vs card. Strategy pattern.
- Chain of Responsibility — Coin routing through validators. Chain of Responsibility pattern.
6. Implementation
Go
package vending
type Product struct {
SKU, Name string
}
type Slot struct {
Code string
PriceCents int
Quantity int
Product Product
}
type VendingMachine struct {
Slots map[string]*Slot
Inserted int
Selected string
CashBox *CashInventory
}
func (machine *VendingMachine) InsertCoin(cents int) { /* ... */ }
func (machine *VendingMachine) Select(code string) error { /* ... */ }
func (machine *VendingMachine) Vend() error { /* decrement, change */ }JavaScript
class VendingMachine {
constructor({ slots, cashInventory }) {
this.slotsByCode = new Map(slots);
this.insertedCents = 0;
this.selectedCode = null;
this.cashInventory = cashInventory;
}
insertCoin({ cents }) { /* ... */ }
selectSlot({ code }) { /* ... */ }
vend() { /* ... */ }
cancel() { /* refund */ }
}7. Concurrency / Thread Safety
- Collisions: Operator restocking while purchase in flight; two customers on networked twins (out of scope for single unit).
- Granularity: Mutex around inventory updates during
Vend. - Go:
sync.MutexonVendingMachinepublic methods.
8. Extensibility & Followups
- Age-restricted slots requiring attendant unlock.
- Telemetry for jam detection and temperature alarms.
- Edge cases: exact change impossible with current float; display warning.
Last updated on
Spotted something unclear or wrong on this page?