Another powerful feature of the command pattern is the clear-cut means it provides
for implementing undo, redo, queuing, and logging features. We all know how valuable
the undo feature is in any productivity application, including games. Because the
command object encapsulates execution of commands, it can just as easily encapsulate
undo() command to reverse itself and go back
to its previous state.
We need to expand the command interface to declare an
undo() command. However, before we proceed, let's stop and think
about how to implement this feature. To implement undo, we need to keep track of
executed commands using a command stack. A stack is a data structure that's based on
the last-in-first-out (LIFO) principle. Stacks implement
pop() operations that
store and retrieve items from it. The pop operation always retrieves the last item
pushed. This is exactly what we need to implement undo, as it simply reverses the
last command. Whenever a command is executed, its command object should be pushed
into a stack. Ideally there should be only one command stack per application. When
the user wants to undo the last command, the stack should be popped, and the
undo() command of the popped command object
should be executed.
Instead of declaring a pure interface, we will declare an abstract interface for commands that support undo. We'll do this to implement the command stack feature within the command class. ...