Part 8 of this series of articles concluded our discussion of services in the CAB.
This article and part 10 of this series will talk about commands in the CAB. Commands are a neat way of implementing the Command design pattern. This article will briefly recap what the Command pattern is and why it is useful. Part 10 will show how this is implemented in the CAB.
The Basics of the Command Pattern
‘Command’ is a design pattern from the original ‘Design Patterns’ book by Gamma, Helm, Johnson and Vlissides (the ‘Gang of Four’). The intent of the pattern is to:
“Encapsulate a request as an object, thereby letting you parameterize clients with different requests.”
The class diagram for this is below:
The Command Class and Interface
The diagram looks more difficult than it is. What it is saying is that we define a simple interface, ICommand, which always has just one method, Execute (with no parameters and no return value). We then implement this interface on various Command classes. So a Command is just a class that does something useful in response to an ‘Execute’ call. However, because all our commands implement Execute using the same interface we have polymorphism: we can use them interchangeably in client code without having to change the client code.
In the class diagram above the Invoker is just any code that calls the Execute method on a Command object through its ICommand interface. This will usually be done in a way that allows us to use the polymorphism discussed above. That is, we should be able to swap around which underlying Command object the Invoker is calling, without the Invoker having to change.
In the simplest case the Execute method itself can just ‘be’ the command: it will do something useful. That may lead to our Command objects being very complicated however, so we may split out the underlying functionality into another class. This is the Receiver in the class diagram above. With a Receiver, whenever the Execute method is called on our Command it simply relays the call to the Receiver class which then does the work. If the command is complex there may be more than one Receiver class, with the Command class calling the Receivers as appropriate.
In the diagram above we also have the usual Gang of Four ‘Client’ class. This is code that gets us started by creating the other classes and hooking them up appropriately so that they will work. In real applications this may well be more than one class, but it makes the diagram neater to bucket all this functionality into one neat little box.
In the Command pattern the client code will instantiate our Commands and Receivers and give the Command objects appropriate references to the Receiver objects.
Finally note that in this pattern we are not passing any parameters to our Command objects, or returning any values from them. The method signature we are using is void Execute().
Why Is This Useful?
This pattern is useful because it decouples the code for actually executing a command from the code that calls the command code, providing a logical separation of duties and making the code easier to maintain.
Furthermore the pattern encapsulates the command logic in classes (the Receivers, if any, and the Command) that have a clearly defined interface. This lets us flexibly change which command we use in different circumstances using polymorphism.
For example we may have a class or set of classes that perform actions (our invokers), but want to vary those actions in a simple way based on the current state of the system. We can encapsulate the varying actions themselves into Command classes and then tell the invoker which one to use depending on the system state.
The canonical example here, as discussed in the Design Patterns book, is a menu system in an application. The book describes how menu ‘toolkits’ are usually written as part of a framework, meaning that we need some way to allow a developer to write code to respond to menu events without having access to the menu code itself. We can do this by allowing the developer to write the commands and assign them to the Invokers (the menu items), without having to change the Invokers. Also, with menus we DO have the situation where we might want to swap around the commands that an Invoker is invoking.
For example, we might have a File/New menu item. This might create a different sort of ‘new’ item depending on what screen the application was displaying. If the application was displaying a report it might create a new report; if the application was displaying a list of users it might create a new user; and so on. We could set this up so that the menu item was given a Command object and simply invoked it when File/New was selected. We could then have CreateNewReportCommand and CreateNewUserCommand objects that the client code would give to the menu item as the screens in the application changed. The menu itself wouldn’t then need any business logic, nor would the code behind the screen it was hosted on.
.NET Delegates, .NET Events and the Command Pattern
It’s also worth bearing in mind that in many ways a simple use of a .NET delegate is a Command pattern, albeit a cumbersome one. The delegate itself is the command. It points to one or more methods in classes which are our Receivers. There will be some code to create the delegate and point it at the methods, which is the Client. Finally there will be some code to invoke the delegate (via the Invoke method), which is our Invoker.
Similarly .NET events, which are just special sorts of delegates, can be viewed as an implementation of the Command pattern.
This is fine, and of course very useful. But as we will see in part 10 the CAB gives us a more explicit way of using the pattern which is both simple and powerful.
.NET Menu Systems and the Command Pattern
Menu systems are a key use for the Command pattern as far as the Gang of Four are concerned. Normally in the .NET framework we use events for hooking up menu and toolbar items to underlying code. As discussed above, this can be regarded as an implementation of the Command pattern. However, the CAB implementation of the Command pattern is specifically intended to be used for menu systems and to replace the normal approach. We will examine the benefits it gives in part 10.
Data and Object Factory Page on the Command Pattern
‘Gang of Four’ Book: Design Patterns: Elements of Reusable Object-Oriented Software
‘Head First Design Patterns’ (excellent book, although Java-based):