Wednesday, April 6, 2011

Design Pattern : Command

The Command pattern allows requests to be encapsulated as objects, thereby allowing clients to be parameterized with different requests, queue or log requests, and support undoable operations.It falls into Behavioral category.

Illustration: - Menus implemented using command

  • Each choice in a Menu is an instance of a MenuItem class. An Application class creates these menus and their menu items along with the rest of the user interface. The Application class also keeps track of Document objects that a user has opened.
  • The application configures each MenuItem with an instance of a concrete Command subclass. When the user selects a Menuitem, the Menuitem calls Execute on its command, and Execute carries out the operation.
  • MenuItems don’t know which subclass of Command they use. Command subclasses store the receiver of the request and invoke one or more operations on the receiver.
  • For example, PasteCommand supports pasting text from the clipboard into a Document. PasteCommand’s receiver is the Document object it is supplied upon instantiation. The Execute operation invokes Paste on the receiving Document.
  • OpenCommand’s Execute operation is different: it prompts the user for a document name, creates a corresponding Document object, adds the document to the receiving application, and opens the document.
image imageimage

In each of these examples, notice how the Command pattern decouples the object that invokes the operation from the one having the knowledge to perform it. This gives us a lot of flexibility in designing our user interface. An application can provide both a menu and a push button interface to a feature just by making the menu and the push button share an instance of the same concrete Command subclass. We can replace commands dynamically, which would be useful for implementing context-sensitive menus. We can also support command scripting by composing commands into larger ones. All of this is possible because the object that issues a request only needs to know how to issue it; it doesn’t need to know how the request will be carried out.

Solution

  • Command decouples the object that invokes the operation from the one that knows how to perform it. To achieve this separation, the designer creates an abstract base class that maps a receiver (an object) with an action (a pointer to a member function). The base class contains an execute() method that simply calls the action on the receiver.
  • All clients of Command objects treat each object as a "black box" by simply invoking the object's virtual execute() method whenever the client requires the object's "service".
  • Sequences of Command objects can be assembled into composite (or macro) commands.

Applicability

Use the Command pattern when you want to

  • parameterize objects by an action to perform, as MenuItem.
  • You can express such parameterization in a procedural language with a callback function, that is, a function that’s registered somewhere to be called at a later point. Commands are an object Oriented replacement for callbacks.
  • Specify, queue, and execute requests at different times. A Command object can have a lifetime independent of the original request. If the receiver of a request can be represented in an address space-independent way, then you can transfer a command object for the request to a different process and fulfill the request there.
  • Supports Undo
  • Support logging changes to that they can be reapplied in case of a system crash. - Recovering form a crash involves reloading logged commands form disk and re-executing them with the execute operation.
  • Structure a system around high-level operations built on primitives operations. Such structure is common in information system that support transactions.

Structure

image

Collaborations

  • The client creates a ConcreteCommand object and specifies its receiver.
  • An Invoker object stores the ConcreteCommand object.
  • The invoker issues a request by calling Execute on the command. When commands are undo-able, ConcreteCommand stores state for undoing the com-mand prior to invoking Execute.
  • The ConcreteCommand object invokes operations on its receiver to carry out the request.

The following diagram shows the interactions between these objects. It illustrates how Command decouples the invoker form the receiver ( and the request it carries out ).

image

Consequences

The Command pattern has the following consequences:

  1. Command decouples the object that invokes the operation from the one that knows how to perform it.
  2. Commands are first-class objects. They can be manipulated and extended like any other object.
  3. You can assemble commands into a composite command. An example is the Macro Command class described earlier. In general, composite commands are an instance of the Composite pattern.
  4. It’s easy to add new Commands, because you don’t have to change existing classes

Model:

image

No comments: