Introduction

One of the more frequently used ‘Gang of Four’ design patterns is the Command Pattern. This pattern has nothing to do with ADO.NET and everything to do with communication between the UI and the other tiers of a multi-tier application. The pattern provides several benefits to an application; most significantly, an unlimited undo/redo capability.

The application attached to this article demonstrates how to use the Command Pattern in real-world code. I wrote the application as a learning exercise, and I invite comments from readers about the implementation of the pattern, and about best practices that might be incorporated into the program.

The Calculator Application

The application emulates a simple four-function RPN calculator:

‘RPN’ stands for ‘Reverse Polish Notation’. Anyone who has used an HP-12C financial calculator knows how it works; for everyone else, here is a brief explanation:

RPN calculators do not have an ‘=’ key. To perform a calculation, the first number is added to the calculator’s register using the ‘+’ button. Then the second number is entered, and the desired operation is selected by clicking the appropriate button. For example, to multiply 2 x 3, the user clicks the following buttons:

Click ‘2’, then ‘+’: The number ‘2’ appears in the display.

Click ‘3’, then ‘x’: The number ‘6’ appears in the display.

Calculations can be chained by entering the next number, then clicking the desired operation button. For example, to add 2 to the above result, click ‘2’, then ‘+’. The number ‘8’ will appear in the display.

The calculator has ‘Clear’ (‘C’) and ‘Correct Error’ (‘CE’) keys. The ‘C’ key clears the register (resets it to zero), and the ‘CE’ key removes the last digit entered in the display.

It also has ‘Undo’ and ‘Redo’ buttons. Each time the ‘Undo’ button is clicked, it undoes an operation, starting with the most recent. The ‘Redo’ button redoes undone operations. The calculator supports unlimited Undo and Redo operations.

Here’s an interesting feature about Undo and Redo: Let’s say I enter 10 operations into the calculator, and then undo four of them. I can redo all four undone operations by clicking the ‘Redo’ button four times. Or, instead of redoing operations, I can enter a new operation. If I enter a new operation, it cuts off my ability to restore the four undone operations, because it renders the state of the calculator’s register inconsistent with the undone operations.

So, I lose the four undone operations. However, after entering the new operation, it is undoable, and the six operations that came before it are also undoable. In other words, entering a new operation destroys any undoes that might otherwise be redone, but it preserves all history that has not been undone.

Finally, the calculator has a ‘log’ field, similar to a paper tape, which records the sequence of calculations, including Undo and Redo operations.

How the Command Pattern Fits In

It is an almost trivial task to emulate a simple RPN calculator. A form, some buttons, a button handler for each one, and a couple of text boxes, and we’re done. The code amounts to simple addition, subtraction, and so on. It shouldn’t run to more than a few lines, at most.

Adding Undo and Redo capabilities complicates things. I might be able to add the ability to undo the last number entered by adding a variable or two, but suppose I want to add support for unlimited Undo and Redo operations? If the user enters 100, or even 1000 operations, they should be able to click the Undo button 100 or 1000 times to undo them all, then click the Redo button the same number of times to redo them all.

That looks like a daunting task, but the Command Pattern makes it surprisingly easy. Basically, what we do is wrap each command in an object, which we will add to a list (which we call the History list) when the command is executed. Then, to undo or redo, we simply move up and down that list.

How Model-View-Controller Fits In

The demo application implements the command in a Model-View-Controller framework. The demo application’s classes are named to match this architecture.

The View has the responsibility of managing the UI—get user input and display results. The Model contains the business rules for our calculator—the code that describes ‘how to act like a calculator’. The Controller sits between the View and the Model. In the demo app, the Controller acts as a command processor. Its primary responsibility is to maintain the History list that enables Undo/Redo functionality.

Without the Command pattern, the Controller would have to act as a sort of traffic cop between the View and the Model. It would receive requests from the View and direct them to the appropriate methods of the Controller. The benefit of using a traffic cop is that it isolates the View and the Model from each other. The View doesn’t have to know about the Model—it can behave in a ‘Viewish’ manner. And the model doesn’t have to know anything about the View—it can behave in a ‘Modelish’ manner. The Controller stands between them, interpreting requests and (sometimes) results.

In most MVC implementations, there is a notable exception to this principle of isolation. The Model typically fires events to announce its state changes, and passes along appropriate information about the state change in event arguments. The View can subscribe directly to these events to update itself, without going through the Controller. This architecture takes some of the load off the Controller.

How the Command Pattern and MVC Work Together

The Command Pattern takes more of the load from the Controller. Each Command object knows which method to call on the Model to do its work, and it knows which method to call to undo its work. So, instead of the Controller having to know how to route requests from the View, it need only call the Command object’s Execute() method. This approach keeps the Controller from becoming overburdened and frees it for other work, in this case managing the History list.

How the Command Pattern Is Implemented

The demo application implements the Command Pattern in a relatively straightforward manner. Here’s the UML representation of the classic GoF Command Pattern:

Since the demo application has only one form in its UI, the program locates the Application functions in View.cs. In a more complex app with multiple forms, this functionality would be stripped out of the UI and located in a separate class.

In the Command Pattern, the Client (the Application class) instantiates a concrete Command object to represent a request to be made of a Receiver. The concrete Command is passed to an Invoker (such as a button-click event handler) as the object’s base type. In other words, we have a concrete Command class for each request that might come from the UI.

In the demo application, we have a CommandAdd class, a CommandSubtract class, and so on. All of these classes are derived from the abstract Command class. Each has its own implementation of the Execute() and the Undo() methods specified in the base class. Since these classes have the same methods, implemented differently, we can pass them back and forth as their base type.

That means the buttons that create the classes, and the Controller that uses them, see all these different objects as being of the same type—Command. That’s how we can store different types of objects in the same History list without having to figure out the specific type we are dealing with. It is the essence of polymorphism.

The Client assigns each Command object to an Invoker object. In the demo application, the invokers are all .NET Button objects. The Command objects are ‘wired’ to the buttons by means of event handlers. For example:

When the ‘+’ button is clicked, the buttonAdd_Click() event handler is called. The handler creates a new CommandAdd object, declaring it as its base type. Then, the handler sends the Command object to the Controller with instructions to execute the command.

The Controller executes the command as follows:

publicvoid ExecuteCommand(Command command)
{
// Purge history listthis.TrimHistoryList();
// Execute the command and add it to the history list
command.Execute();
m_HistoryList.Add(command);
// Move the 'next undo' pointer to point to the new command
m_NextUndo++;
}

First, the Controller calls its TrimHistoryList() method to clear any undone items from the history list. That’s because executing the Command will cut off our ability to redo those commands. Then, it calls the Command object’s Execute() method. After that, it adds the Command object to the History list. And finally, it increments its ‘Next Undo’ pointer, so that it will point to the newly-added Command object.

When the Controller calls the Command object’s Execute() method, that method calls the method in the Model that will accomplish the task that needs to be done:

publicoverridevoid Execute()
{
m_Model.Add(m_Operand);
}

That’s how the request gets routed from the View, through the Controller, to the Model. The Command object has assumed the ‘traffic cop’ responsibility that would otherwise fall on the Controller.

The method called on the Model performs the calculation needed, creates a log entry for the on-screen log field, and fires a DisplayChange event. Here is an example from the Model class:

When the DisplayChange event fires, the View (which subscribes to the event) runs its DisplayChange event handler, which updates the Display and Log fields.

Undo and Redo

Even without undo and redo capabilities, the Command Pattern is a useful participant in an MVC framework, because of the load it takes off the Controller. But Undo and Redo capabilities are probably the reason most developers think of the pattern.

Implementing undo is rather simple. When the ‘Undo’ button is clicked, its event handler sends an ‘Undo’ message to the Controller:

privatevoid buttonUndo_Click(object sender, EventArgs e)
{
/* Note that we don't create a Command object for Undo.
* That's because it wouldn't make sense to undo an undo.
* We could simply redo the action that was undone. Nor
* would it make sense to redo an undo. */
m_Controller.Undo();
}

As the code notes, we don’t use a Command object for this request, because it would not make sense.

When the Controller receives the request, it undoes the last operation added to the History list:

All it really has to do is call the Command object’s Undo() method; the rest of the work is housekeeping for the History list.

In the demo application, a Command object’s Undo function simply calls the inverse operation of the one called in the Execute() function. If Execute() calls Model.Add(), then Undo will call Model.Subtract(). The Undo() method uses the same operand as was used in the Execute() method; this value is stored as a member variable of the Command object.

When a command is undone, it is not removed from the History list. Instead, a ‘Next Undo’ pointer is decremented to point to the previous item in the History list. This approach makes redo operations easy. At any point in time, the first command to be redone is the one after that which ‘Next Undo’ points to. So we simply get that item, call its Execute() method, and increment the ‘Next Undo’ pointer, so that it points to the redone item. In short, Undo and Redo are simple matters of traversing up and down the History list.

Advantages and Disadvantages of the Command Pattern

The main benefits of the Command Pattern are discussed above. The major disadvantage of the pattern is that it results in lots of little Command classes that can clutter up a design. However, the routing information that Command objects encapsulate has to go somewhere. If this information is not contained in Command objects, then it will have to go into the Controller. The resulting bloat may necessitate partitioning the Controller into a subsystem, and it will certainly make the Controller harder to understand and maintain.

A related benefit of the Command class is that it makes it easier to add new functions to an application. If we add a new capability, we no longer need to reopen the Controller class to code routing information. Instead, we encapsulate the information in a Command object and assign it to whatever control we use in the View to invoke the new capability. When the Command gets passed to the Controller, the Controller can use it to route the request, without knowing anything about it. If you remember The Matrix, it’s almost as cool as Trinity downloading the knowledge of how to fly a helicopter.

Call for Comments

As I noted at the beginning of this article, I developed the demo application as a learning exercise in MVC and the Command Pattern. I would very much like to see comments from other developers who have addressed the same issues. Have you approached the problem differently? What have I missed? What would you consider to be best practices in the area? What other advantages and disadvantages do you see in the pattern? Thanks for your feedback; it is genuinely appreciated.

Share

About the Author

David Veeneman is a financial planner and software developer. He is the author of "The Fortune in Your Future" (McGraw-Hill 1998). His company, Foresight Systems, develops planning and financial software.

Comments and Discussions

I'm always struggling with the amount of functionality exposed in the interface of the model. For example in your case you expose the complete "mathematical functions", like add, multiply, .... And then have commands that work on these functions. I'm working on an application that is growing in complexity I find myself adding more and more functions, that will simply expose internal data members. And I can't find a way to successfully strip this down into a bare minimum. Additionally I ask myself whether the integrity of the model is conserved if the modifiers on the model are exposed publically. Everybody could do an "add" directly on the model without using the command pattern and then the undo history will completely hosed up.

As a solution, a command factory was already suggested. So the commands are created from the business logic and only the commands have access to the mutable interface of the model. But still I'm not really convinced, since the amount of functions in the interface will increase with every command and therefor the extensibility of the model is limited. Wouldn't it be better, that the "AdderCommand" will do the "add" itself and only retrieve and store the value in the model. This way, you can extend the model with new commands, without changing anything at the model. But in this case the Model is only a dump data container, that will expose to many details.

Consider an image application. Naturally the image is the model. Now we have functions, like rotate, scale, filter, mirror, invert, reduceColor and so on. Nobody would ever expose every possible function from the image model. But someone has to implement and offer a function to trigger the logic of the algorithm. If it is not the model, who else? The command, some special filter class, and what is a replaceable implementation of the model, if the undelaying model should be e.g. exchanged from an image to a vector graphic. The scaling algorithm are completely different in the two cases. This again would argue for a factory pattern.

Or am I demanding to much from MVC?

I'm seeking for some open source application that did a good implementation of a MVC architecture on a more complex model.

Obviously, keep the interface as narrow as possible. Instead of trying to expose every possible function, expose as little as possible. IMO reuse is often overblown, with the result that components have much broader interfaces than are needed. The drawbacks of that approach are pretty obvious and are well-documented.

The purpose of a Command object is to encapsulate information about a command, not to perform the task referenced by a command. If work is moved out of the model and into command objects, then we may as well dispense with the model and do work in the Command objects. At that point, we are out of OO programming and back to old-style modular programming.

My suggestion: Decide first on the design goals for your model. Don't try to make it all things to all people--plan on extending it if and as you reuse it in later projects. About a third of the GoF patterns were developed to facilitate this approach. You will reduce the complexity of your model and actually improve its maintainability.

This is something that has always confused me with the MVC model.. how much logic does the actual model have? For example, if a themometer is modeled and the temperature is stored in farenheit, should the model provide a temperatureInCelsius() function, or should this be defined somewhere else? From your post it seems that the answer is 'it depends'

The model should incorporate business rules and logic. Ask yourself the following: If I need to move this model to another application, what would make that task easiest. If the thermometer application will always need a temperatureInCelsius() function, then the function could easily go in the model. But if the function would only be required in a specific application (say, a temperatureInKelvin() function), then it would probably go in the service layer of the app.