Labels

Friday, November 19, 2010

Command Design Pattern - Behavioural

1.1     Definition

-  Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and  support undoable operations.      
-       In Command pattern objects are used to represent actions. A Command object encapsulates an action and its parameters.
      

1.2     Intent

There are times when developing an application framework that you need to pass requests between objects without knowing anything about operation requested or the receiver of the request. By encapsulating the request as an object itself, one can "parameterize clients with different requests, queue or log requests, and support undoable operations." (GOF) This is the Command behavioral design pattern. You can separate the requesting object from the object that "knows" how to fulfill it.

1.3     Motivation

In object-oriented programming, the Command pattern is a design pattern in which objects are used to represent actions. A command object encapsulates an action and its parameters.
For example, a printing library might include a PrintJob class. A user would typically create a new PrintJob object, set its 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.
In this case, the same functionality could be exposed via a single SendJobToPrinter() procedure with many parameters. As it takes more code to write a command class than to write a procedure, there must be some reason to use a class. There are many possible reasons:

·         It can improve API design. In some cases, code that uses a command object is shorter, clearer, and more declarative than code that uses a procedure with many parameters. This is particularly true if a caller typically uses only a handful of the parameters and is willing to accept sensible defaults for the rest.
·         A command object is convenient temporary storage for procedure parameters. It can be used while assembling the parameters for a function call and allows the command to be set aside for later use.
·         A class is a convenient place to collect code and data related to a command. A command object can hold information about the command, such as its name or which user launched it; and answer questions about it, such as how long it will likely take.
·         Treating commands as objects enables data structures containing multiple commands. A complex process could be treated as a tree or graph of command objects. A thread pool could maintain a priority queue of command objects consumed by worker threads.
·         Treating commands as objects supports undo-able operations, provided that the command objects are stored (for example in a stack)
·         The command is a useful abstraction for building generic components, such as a thread pool, that can handle command objects of any type. If a new type of command object is created later, it can work with these generic components automatically. For example, in Java, a generic ThreadPool class could have a method addTask(Runnable task) that accepts any object that implements the java.lang.Runnable interface.

1.4     Uses for the command object

Command objects are useful for implementing:

Multi-level undo
   
If all user actions in a program are implemented as command objects, the program can keep a stack of the most recently executed commands. When the user wants to undo a command, the program simply pops the most recent command object and executes its undo() method.
Transactional behavior

Undo is perhaps even more essential when it's called rollback and happens automatically when an operation fails partway through. Installers need this. So do databases. Command objects can also be used to implement two-phase commit.
Progress bars

Suppose a program has a sequence of commands that it executes in order. If each command object has a getEstimatedDuration() method, the program can easily estimate the total duration. It can show a progress bar that meaningfully reflects how close the program is to completing all the tasks.
Wizards

Often a wizard presents several pages of configuration for a single action that happens only when the user clicks the "Finish" button on the last page. In these cases, a natural way to separate user interface code from application code is to implement the wizard using a command object. The command object is created when the wizard is first displayed. Each wizard page stores its GUI changes in the command object, so the object is populated as the user progresses. "Finish" simply triggers a call to execute(). This way, the command class contains no user interface code.
GUI buttons and menu items

In Swing programming, an Action is a command object. In addition to the ability to perform the desired command, an Action may have an associated icon, keyboard shortcut, tooltip text, and so on. A toolbar button or menu item component may be completely initialized using only the Action object.
Thread pools

A typical, general-purpose thread pool class might have a public addTask() method that adds a work item to an internal queue of tasks waiting to be done. It maintains a pool of threads that execute commands from the queue. The items in the queue are command objects. Typically these objects implement a common interface such as java.lang.Runnable that allows the thread pool to execute the command even though the thread pool class itself was written without any knowledge of the specific tasks for which it would be used.
Macro recording

If all user actions are represented by command objects, a program can record a sequence of actions simply by keeping a list of the command objects as they are executed. It can then "play back" the same actions by executing the same command objects again in sequence. If the program embeds a scripting engine, each command object can implement a toScript() method, and user actions can then be easily recorded as scripts.
Networking

It is possible to send whole command objects across the network to be executed on the other machines, for example player actions in computer games.

1.5     Structure




1.1     Participants

 The classes and/or objects participating in this pattern are:


Command  
declares an interface for executing an operation

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

Client  
creates a ConcreteCommand object and sets its receiver

Invoker  
asks the command to carry out the request

Receiver  
knows how to perform the operations associated with carrying out the request.


1.2     Typical Usage

The GOF recommend using the Command pattern when you want to:

·         parameterize objects by an action to perform (much like SqlCommands allowing different types of command text and execute methods)
·         specify, queue, and execute requests at different times. Your Command object may live independently of a request
·         support undo. State can be stored on the Command object, and an "undo" operation performs a "reverse" of the execute. For unlimited undo/redo, a list of Commands could be maintained, and one could traverse it backwards or forwards calling "undo" or "execute" appropriately
·         build systems from "primitive or atomic operations" such as transactions


·          

1.3     Sample Code

This code demonstrates the Command pattern which stores requests as objects allowing clients to execute or playback the requests.


class Invoker
  {
    private Command command;

    public void SetCommand(Command command)
    {
      this.command = command;
    }

    public void ExecuteCommand()
    {
      command.Execute();
    }   
  }

abstract class Command
  {
    protected Receiver receiver;

    // Constructor
    public Command(Receiver receiver)
    {
      this.receiver = receiver;
    }

    public abstract void Execute();
  }
class ConcreteCommand : Command
  {
    // Constructor
    public ConcreteCommand(Receiver receiver) : base(receiver)
    { 
    }

    public override void Execute()
    {
      receiver.Action();
    }
  }
class Receiver
  {
    public void Action()
    {
      Console.WriteLine("Called Receiver.Action()");
    }
  }


class MainApp
  {
    static void Main()
    {
      // Create receiver, command, and invoker
      Receiver receiver = new Receiver();
      Command command = new ConcreteCommand(receiver);

      Invoker invoker = new Invoker();
      invoker.SetCommand(command);
      invoker.ExecuteCommand();

      // Wait for user
      Console.Read();
    }
  }

Output - 

Called Receiver.Action()

1.4     Command Design Pattern in WPF

Windows Presentation Foundation (formerly codenamed "Avalon"), or WPF for short, is a brand new Microsoft framework for developing very rich and powerful Windows applications. It will ship as part of Windows Vista, the next major version of Windows that will be released in the coming months, but WPF will also be available on Windows XP SP2 and Windows Server 2003. There is much to be said about Windows Presentation Foundation and its numerous new and enhanced capabilities, but this article will in stead focus on an old trusted friend, who has finally been given a dedicated room in the big house of Windows User Interface development: the "Command" pattern. This design pattern basically abstracts all actions the user can perform in an application into the notion of "commands"; it has been implemented in many different ways on top of various UI frameworks, but now, it has finally made it into the gut of the system itself. Note that this article is based on a public preview of WPF, so it's possible that there are implementation details that will change over time as the product matures into completion.



Hope this helps.

Thanks & Regards,
Arun Manglick

1 comment:

  1. If you'd like to learn more about java technology visit our Geek's Guide on Java training.

    There you'll find recorded webcasts, videos, white papers, and free tools that can teach you

    all you need to know about this cool and often overlooked technology...

    java training

    ReplyDelete