Command
Support tickets about the cart all said the same thing: "I removed the wrong item and there is no way to get it back." Product asked for an Undo button. It sounded like an afternoon of work.
The cart had add, remove and clear, called directly from 12 button handlers. To undo
something you have to know what was done. Nothing recorded it. A call to cart.clear()
ran, the items were gone, and the call itself left no trace anywhere.
A cart supports add, remove and clear, and users want Undo for all three. What would you have to store, and where, so that the last action can be reversed? Think about what clear() destroys.
The idea#
In a restaurant the waiter does not shout your order at the cook. They write it on a slip. Now the request is a thing. It can wait in a queue on the rail. It can be handed to whichever cook is free. It can be struck out if you change your mind. And it is kept for the bill at the end. None of that is possible with a shout.
A method call happens and is gone. A command is the same request stored as an object: what to do, on what, with which values. Once it is an object you can keep it in an array, and an array of what was done is an undo history.
Four roles. The command is the interface, usually execute and undo. A concrete
command is one kind of request. The receiver is the object that does the real work,
here the cart. The invoker runs commands and keeps the history.