CSC/ECE 517 Fall 2007/wiki1b 7 c9

From Expertiza_Wiki
Revision as of 20:49, 1 October 2007 by Ndokuzo (talk | contribs)
Jump to navigation Jump to search

Command Pattern

What is Command Pattern?

Command pattern is a design pattern in which you can encapsulate actions/requests as objects and parametrize other objects with different requests. By this way a program (or simply an object) can request actions and that object will not worry how the computation of the request is made. It allows the program to decouple the requester(client) of an action from the object that performs the action(receiver).

Components of Command Pattern

(The following UML diagram is taken from the book Design Patterns Elements of Reusable Object-Oriented Software)

  • Command: <<interface>> declares an interface for all commands.
  • ConcreteCommand: implements Command interface, defines a binding between a Receiver and an action, and implements execute() method by invoking the corresponding action(s) on Receiver.
  • Client: creates a ConcreteCommand object and sets its receiver.
  • Invoker: asks the command to carry out the request by calling execute() method of ConcreteCommand.
  • Receiver: knows how to perform the operations associated with carrying out a request.

Advantages of Command Pattern

  • A command object is a convenient temporary storage for procedure parameters. A command can be set aside for later use.
  • As we can save commands we can also use these with data structures, and we can call the actions one after another from a queue with a specific order we want or according to their priorities.
  • As it treats the commands as objects, command pattern supports undo-able operations, provided that the operations are stored in a data structure.
  • It helps making the code modular

When Command Pattern is Used?

Implementation of Command Pattern

Java Implementation

public interface Command {
    public abstract void execute ( );
}

public class FireAlarm {
    public void turnOn( ) {
        System.out.println("Fire alarm is on!");
    }
    public void turnOff( ) {
	System.out.println("Fire alarm is off...");
    }
}

public class FireAlarmOffCommand implements Command {
    private FireAlarm myAlarm;
    public FireAlarmOffCommand (FireAlarm a) {
    	myAlarm =  a;
    }
    public void execute( ) {
    	myAlarm.turnOff( );
    }
}

public class FireAlarmOnCommand implements Command {
    private FireAlarm myAlarm;
    public FireAlarmOnCommand (FireAlarm a) {
    	myAlarm =  a;
    }
    public void execute( ) {
    	myAlarm.turnOn( );
    }
}

public class FireStation {
    public void call( ) {
        System.out.println("Fire department is called!");
    }
}

public class FireStationCallCommand implements Command {
    private FireStation myStation;
    public FireStationCallCommand (FireStation fs) {
    	myStation =  fs;
    }
    public void execute() {
    	myStation.call();
    } 
}

public class WaterSprayer {
    public void startSprayWater() {
	System.out.println("Started spraying water!");
    }
    public void stopSprayWater() {
	System.out.println("Stopped spraying water...");
    }	
}

public class WaterSprayerOffCommand implements Command {
    private WaterSprayer myWaterSprayer;
    public WaterSprayerOffCommand (WaterSprayer ws) {
    	myWaterSprayer =  ws;
    }	
    public void execute() {
    	myWaterSprayer.stopSprayWater( );
    }
}

public class WaterSprayerOnCommand implements Command {
    private WaterSprayer myWaterSprayer;
    public WaterSprayerOnCommand (WaterSprayer ws) {
    	myWaterSprayer =  ws;
    }
    public void execute() {
    	myWaterSprayer.startSprayWater( );
    }
}

public class  FireEmergencyButton{
    private int onCommandCount = 3;
    private int offCommandCount = 2;
    private Command [] onCommands; 
    private Command [] offCommands;
    public FireEmergencyButton(){
    	onCommands = new Command [onCommandCount];
    	offCommands = new Command [offCommandCount];	
    }
    public void setCommand ( int order, Command on, Command off) {
    	onCommands[order] = on; 
        offCommands[order] = off;
    }
    public void setOnCommand ( int order, Command on) {
        onCommands[order] = on; 
    }
    void press() { 
    	for(int i=0; i< onCommands.length; i++) 
    	    onCommands[i].execute() ;                           
    }
    void depress() {
    	for(int i=0; i< offCommands.length; i++)
    	    offCommands[i].execute ( );
    }
}

public class TestCommand {
    public static void main(String[] args) {
        WaterSprayer  ws = new WaterSprayer();
        WaterSprayerOnCommand wsOn = new WaterSprayerOnCommand (ws);
        WaterSprayerOffCommand wsOff = new WaterSprayerOffCommand (ws);

        FireAlarm a = new FireAlarm();
        FireAlarmOnCommand alarmOn = new FireAlarmOnCommand (a);
        FireAlarmOffCommand alarmOff = new FireAlarmOffCommand (a);
			
        FireStation fs = new FireStation( );
        FireStationCallCommand fsCall = new FireStationCallCommand(fs);
              
        FireEmergencyButton feb = new FireEmergencyButton();
        feb.setCommand(0, alarmOn, alarmOff);
        feb.setCommand(1, wsOn, wsOff);
        feb.setOnCommand(2, fsCall);   
        
        System.out.println("Fire Emergency Button pressed!");
        feb.press();
        System.out.println();
        System.out.println("Fire Emergency Button depressed!");
        feb.depress();
    } 
} 

Ruby Implementation

class FireEmergencyButton
  def initialize(onCommands, offCommands)
    @onCommands = onCommands
    @offCommands = offCommands
  end
  def press
    @onCommands.each{|command| command.call}
  end
  def depress
    @offCommands.each{|command| command.call}
  end
end

waterSprayOnCommand  = proc{puts "Started spraying water!"}
waterSprayOffCommand  = proc {puts "Stopped spraying water..."}
fireAlarmOnCommand = proc{puts "Fire alarm is on!"}
fireAlarmOffCommand = proc {puts "Fire alarm is off..."}
fireStationCallCommand = proc{puts "Fire department is called!"}

onCommands = []
onCommands << fireAlarmOnCommand  
onCommands << waterSprayOnCommand
onCommands << fireStationCallCommand

offCommands = []
offCommands << fireAlarmOffCommand
offCommands << waterSprayOffCommand  

feb =FireEmergencyButton.new(onCommands, offCommands)
puts "Fire Emergency Button is pressed!"
feb.press
puts ""
puts "Fire Emergency Button is depressed!"
feb.depress

Comparision of Ruby and Java