Command

From CSSEMediaWiki
Revision as of 23:06, 18 October 2010 by Nelson Shaw (Talk | contribs)
Jump to: navigation, search

In the Command pattern objects are used to represent actions. An action and its parameters are encapsulated by a command object.

Contents

Usage

Sometimes you need to issue a request to an object without even knowing anything about the requested operation or the receiving object itself, then it is useful to apply the Command pattern. A situation where to use the Command pattern would be for example the implementation of a menu in a GUI. Every single menu item has its own corresponding concrete command object, which implement a command interface. When the user clicks on a menu item the menu item calls the execute() method of its command object. The execute() method carries out an operation. The concrete commands store the receiver and call up one or more operations on the receiver. Good examples for menu items would be the opening and closing of documents or also pasting some text. Another example would be a PrintJob where PrintCommand objects set the properties (the document to be printed, the number of copies, and so on), and finally call a method to send the job to the printer. Other applications include undo operations, GUI buttons, networking and parallel processing.

The Command pattern has the following advantages:

  • a command object is a convenient place to collect code and data related to a specific action
  • treating commands as objects supports undo-able operations, provided that the command objects are stored (eg in a stack)
  • the construction of a command and the actual execution of that command can happen at different times

UML Diagram

Command.jpg

Participants

Command

  • declares an interface for executing an operation.

ConcreteCommand (PasteCommand, OpenCommand)

  • defines a binding between a Receiver object and an action.
  • implements Execute by invoking the corresponding operation(s) on Receiver.

Client (Application)

  • creates a ConcreteCommand object and sets its receiver.

Invoker (MenuItem)

  • asks the command to carry out the request. This is done by calling the execute() method.

Receiver (Document, Application)

  • knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver.

Example

  • You can find here a nicely explained java code example of the Command Pattern usage in the real world.


The following is an example of the Command pattern put to use in a Trojan Horse application.

The Task class corresponds to the Command class. The ScreenShot is the ConcreteCommand. In this case, the performTask() method is equivalent to the Execute() method. As you can see, the ScreenShot has a specific state attributed to it, in the case the Bitmap image.

Command and ConcreteCommand

A slight variation can be made with this pattern, in that instead of the ConcreteCommand calling the Receiver, the Receiver can call the ConcreteCommand to initiate the command execution. This is what happens in this case, when the remote Implant receives a Task, it calls its performTask() method.

Implant and Task

Using this pattern allows many other concrete sub-classes of Task to be created. This enables various functionality to be added without violating the Open Closed Principle.

Consequences

  • Command decouples the object that invokes the command from the object that responds to the command.
  • Commands can be extended and manipulated like other objects.
  • You can assemble commands into composite commands using the Composite pattern.
  • It's easy to add new commands because existing classes won't be affected by the change.
  • Can lead to a large number of concrete sub-classes made for every command possible. Attention needs to be given to ensuring that the breadth of concrete commands does not become excessive.

Related Patterns

  • Composite: This pattern can be used to implement composite commands.
  • Memento: This pattern can be used to keep the state required to undo a command's effect.
  • Prototype: Sometimes a command can be copied before being placed in the command history. In this case, the original command can act like a prototype that is copied.


Personal tools