Library
8 min read

State

A customer cancelled an order while the rider was standing at their door. The app gave a full refund. The customer also took the food.

cancel() checked if (status !== 'delivered'). That was correct when there were two statuses. By now there were five, and "out for delivery" had been added to assignRider, to markDelivered and to the tracking screen, but nobody had gone back to cancel. Five methods, five statuses, 25 combinations, and the rules for them were spread across if statements in every method.

Your answer

An order moves through placed, cooking, out for delivery and delivered. cancel() and next() should behave differently at each stage. Where would you put the rule for what cancel() does while the order is cooking, so that adding a new stage cannot leave it forgotten?

The idea#

The picture to keep
The traffic signal

Same junction, same cars, same drivers. What you are allowed to do depends on which light is on. And each light knows its successor: green hands over to amber, amber to red. Nobody at the junction holds a rulebook with every case in it. The light that is on right now is the rule.

In one line: The object behaves differently depending on its current state. Each state is its own class that knows what is allowed now and what comes next.