Command

From CDOT Wiki
Jump to: navigation, search

Introduction

The Command Pattern

The idea behind the Command pattern is to encapsulate code that performs specific 'command-like' tasks or requests for an application. A very important part of the command pattern is the abstract command class, which defines an interface to code to. In this class there is an execute operation. When a concrete command class is created, all of the code for one speciffic command goes into this execute operation and runs when it is called.

A good example to mention right from the beginning to help you understand the command pattern quicker is the menu bar at the top of this web browser. The command pattern may very well have been used in the design of this. Go up to the menu and click on 'File'. A bunch of menu options fly down (obviously). Each of these options would be implementations of the command class. New Window, for example, would call the execute operation when clicked and the code inside there would do whatever it has to do to pop open a fresh new browser. Each other option invokes it's own command(s) when clicked. That 's' is in brackets because since the command class is an object, a command can contain and execute multiple commands per single execution. This is also known as a Macro, and you can create macros with ease with the command pattern. Undo / re-do operations, log files, and many other commonly used commands can also be easily implemented with the command pattern.

Commands created with the command pattern are de-coupled from the application that is using them. If you look at the diagram below, you will see that when a concrete command is created, it contains a refrence to a reciever. The reciever is what calls the excecution of a command, and is it's connection to the application.

UML Diagram

Command.gif

Practical Example

Another practical example which made me understand the Command pattern well was the classic remote control example.

Think of a fancy home theatre remote control as an implementation of the Command pattern. Each button on the remote triggers concrete commands. One button may turn on the television, another to turn on the sound system, and another to adjust the volume etc. There are many different buttons on the remote, and it would be easy to add a new command to the remote... just program a new button to do something. You may also have buttons that evoke more than one command, for example turn the tv on and then go to your favourite channel. The reviever would be the VCR or TV on the other end.

Code Examples

The following are implementations of the command pattern

C++

Here is an example of a cut command using the command pattern for a text editor:


class EditorCommandInterface {

 public:
   virtual void execute(TextEditor& target) = 0;
   virtual ~EditorCommandInterface() { }

};

class CutCommand : public EditorCommandInterface {

 public:
   virtual void execute(TextEditor& target) {
     string s = target.GetSelectedText();
     target.DeleteRange(target.GetSelectStart(), target.GetSelectEnd());
     Clipboard.Copy(s);
   }

};

C#

Now here is a fuller implementation using C#

using System;
abstract class Command
{
  protected Receiver receiver;
  public Command(Receiver receiver)
  {
    this.receiver = receiver;
  }
  abstract public void Execute();
}
class ConcreteCommand : Command
{
  public ConcreteCommand(Receiver receiver) : base (receiver) { }
  public override void Execute()
  {
    receiver.Action();
  }
}
class Receiver
{
  public void Action()
  {
    Console.WriteLine("Called Receiver.Action()");
  }
}
class Invoker
{
  private Command command;
  public void SetCommand(Command command)
  {
    this.command = command;
  }
  public void ExecuteCommand()
  {
    command.Execute();
  }
}
public class Client
{
  public static void Main(string[] args)
  {
    Receiver r = new Receiver();
    Command c = new ConcreteCommand(r);
    Invoker i = new Invoker();
    i.SetCommand(c);
    i.ExecuteCommand();
  }
}

Resources

Wikipedia - Command Pattern