Also known as Action, Transaction

Command

Intent

Command is a behavioral design pattern that lets you turn a request into stand-alone object, which can be used to parametrize objects with different requests, queue or log requests, and support undoable operations.

Problem

Imagine that you are working on a new text editor app. You just finished creating a new Button class, which can be used for toolbar buttons, as well as for generic buttons in dialogs.

While all these buttons may look similar, they do different things. This raises a dilemma of where to put the code for various click handlers of individual buttons. The simplest solution is to create tons of subclasses for each button and move there all of the operations that have to be executed after a button gets clicked.

But shortcomings of this idea become apparent very fast. Firstly, you end up with an enormous amount of subclasses. Secondly, the GUI code becomes awkwardly dependent on a volatile code of business logic.

And here is the ugliest part. Some operations, like copying text, could be invoked from several places. For example, you could press a button on the toolbar, or click the context menu item or just hit Ctrl+C. When the app had only buttons, the copy operations lived inside a CopyButton subclass. But now you will have to duplicate the code of copying operation in two other places.

Solution

The Command pattern suggests encapsulating requests into their very own objects called commands. In case if the operation had any parameters, they become fields of a new command class.

Most commands serve as links between clients, which trigger requests and receiving objects, which handle them by performing some operations.

It is easy to make various commands to follow common interface now that their primary method does not have any parameters. Usually, a command interface has just one method that looks as execute(). Once the common interface is created, you can make commands interchangeable in client code which used to be coupled to specific operations.

After applying the Command pattern to our example with the text editor, you will not need tons of Button subclasses. The base class will get a field for storing a reference to a command object. Instead of performing any real work, a button object will delegate the request to a linked command object upon receiving a click from a user. The command will either execute an operation on its own or delegate it to one of the business logic objects.

You can arrange the code of context menus and hotkeys in a similar way. All of these classes will be delegating work to a single command object shared between them.

Thus, command classes will become convenient middle layer between GUI and business logic classes. And that is only a fraction of all Command's benefits!

Real-World Analogy

Ordering at a restaurant

You enter a restaurant and pick a window seat. A waiter takes your order on a piece of paper, brings to the kitchen and stick it to the wall, under all other orders.

As you probably guessed, the paper ticket serves as a command. It remains in a queue until a chef is ready to serve it. The order contains all relevant information required to cook a dish. It allows a chef to start cooking right away instead of running around clarifying the order details.

Structure

Command design pattern
  1. Invoker stores a reference to a Command object and uses it when an operation needs to be executed. Invoker works with commands only via their common interface, which usually exposes just a single execution method. Invokers are not responsible for creating command objects. They usually get a pre-created command from the Client via the constructor.

  2. Command declares the common interface for all concrete commands. The absolute minimum is a single method to run the actual operation.

  3. Concrete commands implement the actual operations. Some commands can be self-contained and immutable, accepting all necessary data just once, via constructor parameters. Others require a Receiver, an external context object.

  4. Receiver contains business logic or data essential to a particular command. Commands may query these objects for additional info or delegate the entire operation to them. In some cases, receiver's code can be merged into command classes for the sake of simplicity.

  5. Client creates and configures Concrete Command objects. Then passes these objects to appropriate Invokers.

Pseudocode

In this example, the Command pattern is used for logging history of executed operations and being able to revert it. Unlike the previous examples, here the application creates new commands each time user interacts with it. Later this helps to list individual commands in the command history.

Before executing the operation, a command creates a backup of the editor's state. After execution, the command puts itself to the history stack.

The client code, such as UI elements, command history and other classes are not coupled to concrete command classes because they all work with commands via the common command interface. This allows adding new commands to the application without changing existing code.

// Abstract command defines the common interface for all concrete commands.
abstract class Command is
    protected field app: Application
    protected field editor: Editor
    protected field backup: text

    // Regular constructor.
    constructor Command(app: Application, editor: Editor) is
        this.app = app
        this.editor = editor

    // Cloning contructor.
    constructor Command(copy: Command) is
        this.app = copy.app
        this.editor = copy.editor
        this.backup = copy.backup

    // This method produces a copy of the command, suitable for saving in
    // history. It's actually the Prototype pattern in action.
    method clone() is
        return new Command(this);

    // A command may backup editor's state prior to executing its action. We
    // must store a copy of the command in history to preserve the backup kept
    // inside. The copy may be used in future to revert editor's state.
    method backup() is
        backup = editor.text
        app.history.push(this.clone())

    // Restore editor's state.
    method undo() is
        editor.text = backup

    // Main command method stays abstract so that each concrete command provide
    // its own implementation.
    abstract method execute()


// Concrete commands.
class CopyCommand extends EditorCommand is
    // The copy operation is not saved to the history since it does not change
    // editor's state.
    method execute() is
        app.clipboard = editor.getSelection()

class CutCommand extends EditorCommand is
    method execute() is
        // Commands, which change editor's state, will be saved to the history.
        backup()
        app.clipboard = editor.getSelection()
        editor.deleteSelection()

class PasteCommand implements Command is
    method execute() is
        backup()
        editor.replaceSelection(app.clipboard)

// Undo is also a command.
class UndoCommand implements Command is
    method execute() is
        editor.undo()


// Global command history is just a stack.
class CommandHistory is
    private field history: array of Command

    // Last in...
    method push(c: Command) is
        Push command to the end of history array.

    // ...first out
    method pop():Command is
        Get the most recent command from history.


// Editor class has an actual text editing operations. It plays the role of
// Receiver: all commands end up delegating execution to editor's methods.
class Editor is
    field text: string
    field cursorX, cursorY, selectionWidth

    method getSelection() is
        Return selected text.

    method deleteSelection() is
        Delete selected text.

    method replaceSelection(text) is
        Insert clipboard contents at current position.


// Application class configures object relations. It acts as a Sender–creates
// and sends command objects to execute some action.
class Application is
    field clipboard: string
    field editors: array of Editors
    field activeEditor: Editor
    field history: CommandHistory

    // Code that assigns commands to UI objects may look like this.
    method createUI() is
        // ...
        copy = new CopyCommand(this, activeEditor);
        copyButton.setCommand(copy);
        shortcuts.onKeyPress("Ctrl+C", copy);

        cut = new CutCommand(this, activeEditor);
        cutButton.setCommand(cut);
        shortcuts.onKeyPress("Ctrl+X", cut);

        paste = new PasteCommand(this, activeEditor);
        pasteButton.setCommand(paste);
        shortcuts.onKeyPress("Ctrl+V", paste);

        undo = new UndoCommand(this, activeEditor);
        undoButton.setCommand(undo);
        shortcuts.onKeyPress("Ctrl+Z", undo);

    // Take the last command from history and run its undo method. Note that we
    // don't know the type of that command. But we don't have to since command
    // knows how to undo its own actions.
    method undo() is
        command = history.pop()
        if (command != null)
            command.undo()

Applicability

When you want to parameterize objects with actions. For example, when you develop a user interface component, such as a menu, you want your users to be able to configure menu items with actions that will be fired when a menu item is clicked.

The Command pattern turns operations into objects that can be linked from various UI elements. An element delegates the work to command objects instead of doing it by itself. A command executes an operation on its own or passes the call to the appropriate object of business logic.

When you want to queue, schedule, or execute operations remotely.

Like any other object, a command can be serialized, which means converting it to a string. That string can be saved to a file or database and retrieved later to be restored as a command object. But here is more! You could send a serialized command over the network, restore and executed it on a remote server.

When you need to be able to undo operations.

The first thing that you need to be able to revert operations is storing history. Although there are many ways to do this, the Command pattern is perhaps the most popular of all.

The command history is a stack composed of executed command objects. Each command creates a snapshot of the application's state before executing the operation. After the operation is completed, the command puts itself into the history stack. Note that it keeps a backup of the application's state at all times. When undo is required, the program takes the first command from the history stack and restores the snapshot stored in it.

This method has two drawbacks. First, it is not that easy to save an application's state, because some of it can be private. This problem can be mitigated with the Memento pattern.

Secondly, the state backups may consume quite a lot of RAM. Therefore, sometimes you can resort to an alternative implementation, where instead of restoring the past state, the command performs the inverse operation. This option also has a price. The reverse operation is often hard or even impossible to implement.

How to Implement

  1. Declare the Command interface with a single execute method.

  2. Start extracting operations into new Concrete command classes that follow common Command interface. Transform operation's parameters into fields in concrete command classes. They should be initialized via command's constructor.

  3. Make sure that command has fields for storing references to any Receiver objects it needs to collaborate with. These fields should also get initial values via the constructor.

  4. Identify Invoker classes and give them fields for storing command objects. Invokers should communicate with command objects only using the Command interface. They usually do not create command objects by themselves, but rather get them from the client code.

  5. The main application's code, acting as Client, should create and configure Concrete commands and pass them to the appropriate Invoker objects. Sometimes multiple Invokers can use the same command objects.

Pros and Cons

  • Decouples classes that invoke operations from classes that perform them.
  • Allows reversal (undo) of operations.
  • Allows deferred execution of operations.
  • Allows assembling simple commands into larger ones.
  • Follows the Open/Closed Principle.
  • Increases overall code complexity by creating multiple additional classes.

Relations with Other Patterns

  • Chain of Responsibility, Command, Mediator and Observer address various ways of connecting senders and receivers of requests:

    • Chain of Responsibility passes a request sequentially along a dynamic chain of potential receivers until one of them handles a request.

    • Command establishes a one-directional connection from senders to receivers.

    • Mediator has senders and receivers reference each other indirectly.

    • Observer passes a request to all concerned receivers at the same time but allows them to subscribe and unsubscribe from receiving further requests dynamically.

  • Handlers in Chain of Responsibility can be represented as Commands. In this case, a lot of different operations may be executed over the same context, represented by the request.

    But there's another approach, where the request itself is a Command object, passed along a chain of objects. In this case, the same operation may be executed over a lot of different contexts, represented as chained objects.

  • Command and Memento can be used together. They can act as magic tokens to be passed around and invoked at a later time. In Command, the token represents a request; in Memento, it represents the internal state of an object at a particular time. Polymorphism is important to Command, but not to Memento because its interface is so narrow that a memento can only be passed as a value.

  • Command and Strategy are very similar, since both used to parametrize context with some action. Command can be used to convert any operation into an object. Operation's parameters become fields of that object. The conversion allows deferred or remote execution, storing command history, etc.

    On ther other hand, the Strategy pattern usually describes different ways of doing the same thing. It helps to interchange these algorythms in a single context class.

  • Prototype can help when you need to save copy of the Command into history.

  • The Visitor pattern is like a more powerful version of the Command pattern that may execute an operation over an object of any type.

Implementations in Different Programming Languages

Java