Vending Machine
Low-Level Design: lesson 14 of 15
Four small objects, each one only answering for its own moment.
Lesson 14 of 15 · 6 min
Vending Machine
Step 1 of 8
Each moment gets its own small object, and the machine holds one of them at a time.
The Idea
Give every state its own small object: idle, paid, dispensing, sold out. Each answers the same actions differently, and a transition is a state replacing itself on the machine.
The machine holds no rules at all — no flags, no chain of checks that has to be repeated in every method.
Real-World Example
A ticket barrier. Tapping your card a second time does nothing, because the gate is already open; the identical tap a moment earlier is what opened it. The gate, not the card, decides.
The Code
class Idle:
def coin(self, m): m.state = Paid(); return "paid"
def select(self, m): return "pay first"
class Paid:
def coin(self, m): return "already paid"
def select(self, m): m.state = Idle(); return "dispensing"
class Machine:
def __init__(self): self.state = Idle()
def do(self, action): return getattr(self.state, action)(self) # no flags
m = Machine()
print(m.do("select"), m.do("coin"), m.do("select"), m.do("select"))
# pay first paid dispensing pay firstThe Tradeoff
Adding "sold out" is one new class plus one changed transition, in Paid, the only state that can sell the last item; the machine itself never changes. But four classes for four labels is a lot of ceremony, and the transition map is scattered instead of readable in one place. Use a table while states are only names.
Your turn
Put the steps in the right order.
- Later actions are answered by the new state object, with no flag consulted anywhere
- An action arrives at the machine
- The machine forwards it to whichever state object it is currently holding
- That state performs the action and, if it is a transition, replaces itself
Mini quiz
1 / 3