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

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.

I'm confused that the download source doesn't correspond with your article, before i log in, the download is a aspx page, the name is
logon.aspx, while then i log in, but still the download isn't the
thing i want, i appears as a TermOfUse aspx page. I don't know why.

Im a single developer so i do analyze,design and implement aloneness. i want seriously to use obeject oriented, documentation(UML) and design patterns in my projects.your article so help me about this.but i have 2 question.
1)I read other messages about communication and dependency between view and model.likewise i understood command pattern logic.i send a view(web page control) as a parameter to command object when create it and use it in command and model objects for access to page(view) controls for example by below code:
(pageObject.FindControl("controlName") as TextBox).Text = "Some text";
whats your opinion about this?

2)I have some education about ntier(specially 3tier) architecture.can you please
take me additional describtion about "class placement in tiers such as boundry and entity
compare and relation between 3tier and MVC

i tell again this article so help me.Thanks so much
Sincerely
Ali Mohammadi

First of all thank you for you contribution.
I have read your article thoroughly since I am designing a complex UI Application that has several views and requires, don't they all, history of actions (redo, undo)

I guess you knowledge in this kind of design is much deeper than the article example.
And so I have the following question:

In the article example the operation on the data can be inverted. For an instance: addsubtract.
What can be done if it not? Let's say an operation of color change:
View is started with color blue the user changed it to green and then to red.

Since each command is encapsulated in an object, you can collect commands in a List object. Each command should have an Undo action method. For example, if the command sets a color, then the Undo() method of the command should reset the color to what it was before the command was executed.

-- Step 1: The user changes blue to green. The command's Undo() method would set the color to blue, and the command is added as List[0].

-- Step 2: The user changes green to red. The command's Undo() method would set the color to green, and the command is added as List[1].

--Step 3: The user selects Undo from your Ddit menu. Pull the last command from the list (List[1]) and execute its Undo() method. The color changes back to green.

--Step 4: The user selects Undo from your Edit menu again. Pull the last command from the list (List[0]) and execute its Undo() method. The color changes back to blue.

You can add as many commands as you like to the list, and different types of commands can be added to the list, so long as each either derives from a base Command object or implements an ICommand interface that you define. I personally prefer the base-class in this contexts since each object derived from the base class has an 'is a" relationship to the base. In other words, each derived class is a command.

I think the original poster's question was more about what if the operation is something like "blur image like crazy". There is no perfect inverse for that operation that can be expressed algorithmically. So the answer is that you just have to save whatever was there before in the command object. If it's a big image, that could be a lot of data. And that's one reason why Photoshop likes to manage its own swap file on a partition other than where your main swap file resides. It has to constantly saves state to its swap file for undos.