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 list
this.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

Good point. The demo app uses a "View in Charge" implementation of MVC. That's not the only way to implement the architecture.

In the case of the demo app, I used that implementation because of its simplicity. But there is an argument that perhaps the View should be in charge of Command objects. It goes like this:

The View is the least stable part of any application. We may run it on a local machine today, as a Web app next year, and as something else two years from now. We want to reuse as much of my existing code base as possible when we do that. In other words, we would like to be able to change the View without having to reopen the Controller or the Model.

One way to do that is to encapsulate the logic of how the View interacts with the Model in Command objects. So when we change the app from a local app to a web app, we simply rewrite the View as a web client, and we rewrite the Command objects that connect it to the Model via the Controller. The Model and the Controller don't need to be changed. In other words, the View and Command objects change together.

Since they change together, the argument goes, Command objects are more naturally bound to the View than to any other part of the system. So, it makes sense that a Command object should get its reference to the Model from the View.

In the real world, of course, things aren't so neat and tidy. If you want to dig more deeply into the issue, I'd recommend Chapter 2 of Rocky Lhotka's "Expert C#/VB.Net Business Objects" book. He works through the issue of "Who is in charge when my architecture is based on distributed objects that are being passed back and forth between different parts of an application?"

Maybe a Command factory would do the trick. The view could then request a Command object of a specific type (like Add), and the factory would take care of creating it with the association to the correct Model. I know its overkill in this situation, but if you had your business logic separated in various Models it could work nicely.

No, there's nothing wrong with it, but I have found that when my View classes get data directly from the model, non-UI code creeps inth the View classes. This code mainly involves the View deciding where in the model it needs to go to get data for display.

I personally have the View request data from dedicated methods in the Controller, rather than directly from the Model. The Controller methods decide where to go in the Model to get the information needed. That keeps my View classes lighter and more focused on their primary responsibility--displaying data--without the distraction of deciding how to get that data.

For another approach to Undo, see Rockford Lhotka, Expert C# Business Objects (Apress 2004) (VB.Net Edition also available). Lhotka implements Undo in a very sophisticated manner, by taking 'snapshots' of an object's state as messages are sent from the UI. The Undo capability is part of his CSLA framework, which I would recommend to any enterprise developer doing OOP design.

One does have to be very careful with Undo/Redo. Because of rounding, undoing a division command with a mulitplication command doesn't always result in the original value. Saving the state of the object prior to performing the division and then restoring the state in the Undo action would probably work better in this case. However, in other cases, storing the state of some objects may be very expensive.

Think it through carefully. I've found that it usually takes a combination of both to efficiently implement Undo/Redo.

Offhand, I don't think it would be terribly difficult. Simply add a property to the command object to reference the document object that generated it. Or, instead of a property, pass in a reference to the document to the command object's constructor and maintain the reference as a member variable.

Then, when the command object is popped from the Undo stack, its Undo() method will perform the required operations on that document. When a document is closed, you can either clear the Undo stack or purge it of commands that refer to the closed document.

Most of the apps I build aren't document type apps, so I don't really need the layered undo facility. But I do like the idea of centralizing functionality, so that some method can be called from selecting a menu item or clicking on a toolbar button, or from a context menu anywhere in the app, and to have all the necessary info/properties for the command all in one place, e.g. icon, tooltip, caption, ...

The intent of the Command pattern is a bit different from that. One can centralize requests without using it. For example, a menu item, a toolbar button, and a context menu item can simply be wired to the same event handler.

MVC architecture is intended to provide centralization of functionality, and can be used to provide it without using the Command pattern. For example, even if the menu item, toolbar button, and context menu item are wired to separate event handlers, those handlers would all call the same method in the Controller, which would direct the request to the Model objects that do the actual work. The idea is that the Controller is organized according to the functionality provided by the app, while the View is organized to provide the best user experience.

The key to MVC architecture in .NET is to minimize the code in a Windows Form. Ideally, the form should contain only event handlers for the form's controls, and each of these event handlers should only call a method in the controller. In other words, the Windows Form does no work, other than displaying information and receiving user input.

In either case, centralization is provided without resort to the Command pattern. The pattern adds three benefits to the application: (1) It simplifies the controller, which becomes a simple command interpreter; (2) It makes it easier to expand functionality, since the Controller doesn't have to be reopened when functionality is added; and (3) it provides Undo functionality, if one needs it.

Microsoft has several articles about MVC on MSDN--they (and many others) recommend it as the cornerstone of a web architecture.

The Command pattern could be implemented in a web app, but I would expect a lot of overhead from serializing the objects. So, if it were to be implemented, I would expect to see the objects created by a separate component on the server, which gets called when events fire on the web client.