Design Patterns #5: Command

delayed but here I am with the next design pattern. This time it’s the command pattern. Those who are familiar with the Head First book might be wondering where’s singleton. The Some time ago I wrote a post about singleton (which you can find [here]), so there’s no point in going back. Therefore we go straight to the command.

The command pattern encapsulate calls to objects and provides undo mechanism for those calls. This is achieved by command classes which can perform an action over an object and are assigned to callers. Let’s take a look at the diagram:

Let’s start discussing the above from the ICommand interface and its concrete implementation. The interface has two methods: one for proper action, one for undoing the action. The implementation additionally has reference to IReciever object which defines over what type the command can execute. This is not mandatory, for instance you can declare your execute() and undo() methods to take IReciever as parameter. The important thing is that concrete command operates on certain type, however the caller doesn’t know anything about the receiver, the only responsibility of the caller is (so to speak) to call.

The example in the book is really great. The authors presented a programmable remote controller for an intelligent house. The controller has multiple buttons which can be assigned with a command that can operate lights, home cinema etc.

Our example will be programmable counter. The counter will have 5 buttons to manipulate the value of the counter. The counter will have undo feature. This time the code example will have WinForms GUI with custom controls for buttons-callers and counter-receiver.

The caller will have a button to execute a command and a drop-down list to ‘program’ the button with one of the available commands.

 The receiver will have a text-box with current value, button to reset the counter, button to undo last command and a list of all executed commands (operating in FIFO-like mode, the newest on top, the newest first to undo). This user-control will also implement IReceiver interface which provides integer property CounterValue (which play the role of action() method from the diagram) on which the commands will operate and AddToTrace methods which will be used by a command to enroll itself to a command trace for undoing.

Now, the command. Let’s start with the interface:

Beside two already discussed methods Execute() and Undo() the interface provides also Name property (which will be used by the UI) and Receiver property for referencing the counter on which the command will operate.

Concrete command
Now, let’s take a look at one of the commands which implements ICommand interface:

The Execute() method increments the value of the counter and puts the command to the top of the command trace for undoing. The Undo() method simply does the opposite of the Execute() method which is to decrease the counter by one. Removing it from the command trace will be the responsibility of the undo button in the counter user-control.

Command trace
To make it possible we need to keep track of what commands have been executed. For that reason our counter user-control is equipped with a private list that holds objects of type ICommand. The command can enrol itself to the list by invoking AddToTrace method of the receiver and pass itself as an argument.

Once we have the list we can use the undo button which takes the first element off the command trace and invokes the Undo() method.

And that’s it. Take a look how this operates. 

So, that’s it for today. Don’t forget about the source code below and come back next week!

Source code: ZIP file