Command

From Wikibooks, open books for an open world
Jump to: navigation, search

Chain of responsibility Computer Science Design Patterns
Command
Interpreter

The command pattern is an Object behavioural pattern that decouples sender and receiver. It can also be thought as an object oriented equivalent of call back method.

Call Back: It is a function that is registered to be called at later point of time based on user actions.

public interface Command {
  public int execute(int a, int b);
}
public class AddCommand implements Command {
  public int execute(int a, int b) {
     return a + b;
  }
}
public class MultCommand implements Command {
  public int execute(int a, int b) {
     return a * b;
  }
}
public class TestCommand {
  public static void main(String a[]) {
    Command add = new AddCommand();
    add.execute(1, 2); // returns 3
    Command multiply = new MultCommand();
    multiply.execute(2, 3); // returns 6
  }
}

In the above example, it can be noted that the command pattern decouples the object that invokes the operation from the ones having the knowledge to perform it.

Implementations

Consider a "simple" switch. In this example we configure the Switch with two commands: to turn the light on and to turn the light off.

A benefit of this particular implementation of the command pattern is that the switch can be used with any device, not just a light — the Switch in the following example turns a light on and off, but the Switch's constructor is able to accept any subclasses of Command for its two parameters. For example, you could configure the Switch to start an engine.

Implementation in Java
/* The Command interface */
public interface Command {
   void execute();
}
import java.util.List;
import java.util.ArrayList;
 
/* The Invoker class */
public class Switch {
   private List<Command> history = new ArrayList<Command>();
 
   public Switch() {
   }
 
   public void storeAndExecute(Command cmd) {
      this.history.add(cmd); // optional
      cmd.execute();        
   }
}
/* The Receiver class */
public class Light {
   public Light() {
   }
 
   public void turnOn() {
      System.out.println("The light is on");
   }
 
   public void turnOff() {
      System.out.println("The light is off");
   }
}
/* The Command for turning on the light - ConcreteCommand #1 */
public class FlipUpCommand implements Command {
   private Light theLight;
 
   public FlipUpCommand(Light light) {
      this.theLight = light;
   }
 
   public void execute(){
      theLight.turnOn();
   }
}
/* The Command for turning off the light - ConcreteCommand #2 */
public class FlipDownCommand implements Command {
   private Light theLight;
 
   public FlipDownCommand(Light light) {
      this.theLight = light;
   }
 
   public void execute() {
      theLight.turnOff();
   }
}
/* The test class or client */
public class PressSwitch {
   public static void main(String[] args){
      Light lamp = new Light();
      Command switchUp = new FlipUpCommand(lamp);
      Command switchDown = new FlipDownCommand(lamp);
 
      Switch s = new Switch();
 
      try {
         if (args[0].equalsIgnoreCase("ON")) {
            s.storeAndExecute(switchUp);
         }
         else if (args[0].equalsIgnoreCase("OFF")) {
            s.storeAndExecute(switchDown);
         }
         else {
            System.out.println("Argument \"ON\" or \"OFF\" is required.");
         }
      } catch (Exception e) {
         System.out.println("Arguments required.");
      }
   }
}
Implementation in C#

The following code is an implementation of Command pattern in C#.

using System;
using System.Collections.Generic;
 
namespace CommandPattern
{
    public interface ICommand
    {
        void Execute();
    }
 
    /* The Invoker class */
    public class Switch
    {
        private List<ICommand> _commands = new List<ICommand>();
 
        public void StoreAndExecute(ICommand command)
        {
            _commands.Add(command);
            command.Execute();
        }
    }
 
    /* The Receiver class */
    public class Light
    {
        public void TurnOn()
        {
            Console.WriteLine("The light is on");
        }
 
        public void TurnOff()
        {
            Console.WriteLine("The light is off");
        }
    }
 
    /* The Command for turning on the light - ConcreteCommand #1 */
    public class FlipUpCommand : ICommand
    {
        private Light _light;
 
        public FlipUpCommand(Light light)
        {
            _light = light;
        }
 
        public void Execute()
        {
            _light.TurnOn();
        }
    }
 
    /* The Command for turning off the light - ConcreteCommand #2 */
    public class FlipDownCommand : ICommand
    {
        private Light _light;
 
        public FlipDownCommand(Light light)
        {
            _light = light;
        }
 
        public void Execute()
        {
            _light.TurnOff();
        }
    }
 
    /* The test class or client */
    internal class Program
    {
        public static void Main(string[] args)
        {
            Light lamp = new Light();
            ICommand switchUp = new FlipUpCommand(lamp);
            ICommand switchDown = new FlipDownCommand(lamp);
 
            Switch s = new Switch();
            string arg = args.Length > 0 ? args[0].ToUpper() : null;
            if (arg == "ON")
            {
                s.StoreAndExecute(switchUp);
            }
            else if (arg == "OFF")
            {
                s.StoreAndExecute(switchDown);
            }
            else
            {
                Console.WriteLine("Argument \"ON\" or \"OFF\" is required.");
            }
        }
    }
}
Implementation in Python

The following code is an implementation of Command pattern in Python.

class Switch(object):
    """The INVOKER class"""
    def __init__(self, flip_up_cmd, flip_down_cmd):
        self.flip_up = flip_up_cmd
        self.flip_down = flip_down_cmd
 
class Light(object):
    """The RECEIVER class"""
    def turn_on(self):
        print "The light is on"
    def turn_off(self):
        print "The light is off"
 
class LightSwitch(object):
    """The CLIENT class"""
    def __init__(self):
        lamp = Light()
        self._switch = Switch(lamp.turn_on, lamp.turn_off)
 
    def switch(self, cmd):
        cmd = cmd.strip().upper()
        if cmd == "ON":
            self._switch.flip_up()
        elif cmd == "OFF":
            self._switch.flip_down()
        else:
            print 'Argument "ON" or "OFF" is required.'
 
# Execute if this file is run as a script and not imported as a module
if __name__ == "__main__":
    light_switch = LightSwitch()
    print "Switch ON test."
    light_switch.switch("ON")
    print "Switch OFF test."
    light_switch.switch("OFF")
    print "Invalid Command test."
    light_switch.switch("****")
Implementation in Scala
/* The Command interface */
trait Command {
   def execute()
}
 
/* The Invoker class */
class Switch {
   private var history: List[Command] = Nil
 
   def storeAndExecute(cmd: Command) {
      cmd.execute()
      this.history :+= cmd
   }
}
 
/* The Receiver class */
class Light {
   def turnOn() = println("The light is on")
   def turnOff() = println("The light is off")
}
 
/* The Command for turning on the light - ConcreteCommand #1 */
class FlipUpCommand(theLight: Light) extends Command {
   def execute() = theLight.turnOn()
}
 
/* The Command for turning off the light - ConcreteCommand #2 */
class FlipDownCommand(theLight: Light) extends Command {
   def execute() = theLight.turnOff()
}
 
/* The test class or client */
object PressSwitch {
   def main(args: Array[String]) {
      val lamp = new Light()
      val switchUp = new FlipUpCommand(lamp)
      val switchDown = new FlipDownCommand(lamp)
 
      val s = new Switch()
 
      try {
         args(0).toUpperCase match {
            case "ON" => s.storeAndExecute(switchUp)
            case "OFF" => s.storeAndExecute(switchDown)
            case _ => println("Argument \"ON\" or \"OFF\" is required.")
         }
      } catch {
         case e: Exception => println("Arguments required.")
      }
   }
}
Implementation in JavaScript

The following code is an implementation of Command pattern in Javascript.

/* The Invoker function */
var Switch = function(){
    this.storeAndExecute = function(command){
        command.execute();
    }
}
 
/* The Receiver function */
var Light = function(){
    this.turnOn = function(){ console.log ('turn on')};
    this.turnOff = function(){ console.log ('turn off') };
}
 
/* The Command for turning on the light - ConcreteCommand #1 */
var FlipUpCommand = function(light){
    this.execute = light.turnOn;
}
 
/* The Command for turning off the light - ConcreteCommand #2 */
var FlipDownCommand = function(light){
    this.execute = light.turnOff;
}
 
var light = new Light();
var switchUp = new FlipUpCommand(light);
var switchDown = new FlipDownCommand(light);
var s = new Switch();
 
s.storeAndExecute(switchUp);
s.storeAndExecute(switchDown);
Implementation in Smalltalk
Object subclass: #Switch
  instanceVariableNames:
    ' flipUpCommand flipDownCommand '
  classVariableNames: ''
  poolDictionaries: ''
 
Object subclass: #Light
  instanceVariableNames: ''
  classVariableNames: ''
  poolDictionaries: ''
 
Object subclass: #PressSwitch
  instanceVariableNames: ''
  classVariableNames: ''
  poolDictionaries: ''
 
!Switch class methods !
upMessage: flipUpMessage downMessage: flipDownMessage
 
^self new upMessage: flipUpMessage downMessage: flipDownMessage; yourself.! !
 
!Switch methods !
upMessage: flipUpMessage downMessage: flipDownMessage
flipUpCommand := flipUpMessage.
flipDownCommand := flipDownMessage.!
 
flipDown
flipDownCommand perform.!
 
flipUp
flipUpCommand perform.! !
 
!Light methods !
turnOff
Transcript show: 'The light is off'; cr.!
 
turnOn
Transcript show: 'The light is on'; cr.! !
 
!PressSwitch class methods !
switch: state
" This is the test method "
 
| lamp switchUp switchDown switch |
lamp := Light new.
switchUp := Message receiver: lamp selector: #turnOn.
switchDown := Message receiver: lamp selector: #turnOff.
 
switch := Switch upMessage: switchUp downMessage: switchDown.
 
state = #on ifTrue: [ ^switch flipUp ].
state = #off ifTrue: [ ^switch flipDown ].
 
Transcript show: 'Argument #on or #off is required.'.
! !


Clipboard

To do:
Add more illustrations.


Chain of responsibility Computer Science Design Patterns
Command
Interpreter


You have questions about this page?
Ask it here:


Create a new page on this book: