Tuesday, November 22, 2011

Command Pattern


It is another data-driven pattern. The client invokes a particular module using a command or an Action (Basically calling a method).Command Pattern allows you to decouple the requester of an action from object that actually performs the action by introducing command objects.

Definition:
“Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.”
Head First Java
Command Pattern at First Glance:
I will be a bit violent here but this is the best example I could ever think of after reading a lot of content on Command Design Pattern. Let us assume we are living in Germany in the times of Second World War. He is our commanding officer, and at his one command Military, Air Force and Navy would start firing.

Hitler the Commanding Officer

Let us have a look at the Command Pattern from the flow perspective.
Object Creation and Flow


Class Diagram

Before making our hand dirty just let us have a glance at the Structure of Command Pattern.

Class Diagram

Do not bother about this class diagram right away; I am sure we will understand it after we see the coding. We will be relating our code with the Class diagram

Let us try out Some Coding

We have two interfaces Command and Soldier (Receiver).

public interface Command {
      // Relate this as Execute method in the Class diagram
      void executeFire();
     
      // Relate this to UNDO action
      void executeStopFire();
     
      // Other Actions can also be declared
      void executeHoldBack();
}

public interface Soldier {
      // Various Action to be performed by the Receiver on getting command
      void fire();
      void stopFire();
      void holdBack();
}


Let us create some concrete Receivers of the Commands
  
public class ArmySoldier implements Soldier{

      @Override
      public void fire() {
            System.out.println("Army is Firing");          
      }
      @Override
      public void holdBack() {
            System.out.println("Army is on Hold Back");    
      }
      @Override
      public void stopFire() {
            System.out.println("Army has Stopped Firing"); 
      }
}

public class AirForceSoldier implements Soldier{

      @Override
      public void fire() {
            System.out.println("Air Force is Firing");           
      }
      @Override
      public void holdBack() {
            System.out.println("Air Force is on Hold Back");     
      }
      @Override
      public void stopFire() {
            System.out.println("Air Force has Stopped Firing");  
      }
}

public class NavySoldier implements Soldier{

      @Override
      public void fire() {
            System.out.println("Navy is Firing");          
      }
      @Override
      public void holdBack() {
            System.out.println("Navy is on Hold Back");    
      }
      @Override
      public void stopFire() {
            System.out.println("Navy has Stopped Firing"); 
      }
}

Let us create some concrete Commands
  
public class ArmySoldierCommand implements Command{
      Soldier armySoldier;
     
      public ArmySoldierCommand(Soldier armySoldier) {
            this.armySoldier = armySoldier;
      }
      @Override
      public void executeFire() {
            armySoldier.fire();
      }
      @Override
      public void executeHoldBack() {
            armySoldier.holdBack();
      }
      @Override
      public void executeStopFire() {
            armySoldier.stopFire();
      }
}

public class AirForceSoilderCommand implements Command{
      Soldier airForceSoldier;
     
      public AirForceSoilderCommand(Soldier airForceSoldier) {
            this.airForceSoldier = airForceSoldier;
      }
      @Override
      public void executeFire() {
            airForceSoldier.fire();
      }
      @Override
      public void executeHoldBack() {
            airForceSoldier.holdBack();
      }
      @Override
      public void executeStopFire() {
            airForceSoldier.stopFire();
      }
}

public class NavySoilderCommand implements Command{
      Soldier navySoldier;
     
      public NavySoilderCommand(Soldier navySoldier) {
            this.navySoldier = navySoldier;
      }
      @Override
      public void executeFire() {
            navySoldier.fire();
      }
      @Override
      public void executeHoldBack() {
            navySoldier.holdBack();
      }
      @Override
      public void executeStopFire() {
            navySoldier.stopFire();
      }
}

Now the most Important class the INVOKER ADOLF HITLER

public class Hitler {
      static List commandList = new ArrayList();
     
      public static void addCommand(Command command){
            commandList.add(command);
      }
     
      public static void executeFireCommand(Command command){
            command.executeFire();
      }
     
      public static void executeStopFireCommand(Command command){
            command.executeStopFire();
      }
     
      public static void executeHoldBackCommand(Command command){
            command.executeHoldBack();
      }
      public static void executeFireAllCommands(){
            Iterator iterator = commandList.iterator();
            while (iterator.hasNext()) {
                  Command command = (Command) iterator.next();
                  command.executeFire();
                 
            }
      }
      // Similarly you can have other methods as per your requirement
}

Let us test use Command Loader (Client) to test our Command Pattern

public class CommandLoader {
      public static void main(String[] args) {
      // Initialising the Soldiers (They are the reciever's of the command)
      Soldier armySoldier = new ArmySoldier();       
      Soldier airForceSoldier = new AirForceSoldier();
      Soldier navySoldier = new NavySoldier();
           
      // Initialising the Concrete Commands
      Command armyCommand = new ArmySoldierCommand(armySoldier); 
      Command airForceCommand = new AirForceSoilderCommand(airForceSoldier);
      Command navyCommand = new NavySoilderCommand(navySoldier);
           
      System.out.println("Hitler Executes Individual Fire Commands");
      Hitler.executeFireCommand(armyCommand);        
      Hitler.executeFireCommand(airForceCommand);
      Hitler.executeFireCommand(navyCommand);
     
      System.out.println("Hitler Executes Individual Stop Fire Commands");
      // Hitler can command his forces as per the plan
      Hitler.executeStopFireCommand(armyCommand);
      Hitler.executeHoldBackCommand(armyCommand);
     
      System.out.println("Hitler Executes All Fire Commands");
      // Here we load all commands to execute all in a Single shot
      Hitler.addCommand(armyCommand);          
      Hitler.addCommand(airForceCommand);
      Hitler.addCommand(navyCommand);
      Hitler.executeFireAllCommands();
      }
}
OUTPUT is as Follows: All this is simple to understand

Hitler Executes Individual Fire Commands
Army is Firing
Air Force is Firing
Navy is Firing

Hitler Executes Individual Stop Fire Commands
Army has Stopped Firing
Army is on Hold Back

Hitler Executes All Fire Commands
Army is Firing
Air Force is Firing
Navy is Firing


By this time we all have understood Command Patterns very well, not is time to relate our classes to the class diagram


One last thing is left to be discussed is UNDO action i.e. to stop the command fire or reverse the state of the command (Think of it like another command). In our example we have already covered it. It’s just that we haven’t yet realized it, for those who are JAVA geeks might have already felt the stopFireCommand() is our undo command. We can have multiple such actions as per our needs.

Real Time Scenarios to Use Command Pattern:
  • This pattern works very well in GUI code (Action Listeners), but it can be applied wherever it is possible and worthwhile to make operations reversible.
  • Commands may also be used to logging,queuing requests and transactional systems.
  • Menu Actions like Cut, Copy and Paste uses Command Pattern
  • It is also possible for a command to be a collection of commands, called a Macro Command. Macro Commands are simple extension of Command that allow multiple commands to be invoked and they can easily support undo operations.
Consequences of the Command Pattern
  • It may lead to a little explosion of classes

6 comments:

  1. Your examples are too good man...You explained one of the most confusing GoF design pattern with ease...hats off :)

    ReplyDelete
  2. Hey Thanks Abhi.....Dude this can't be confusing for you....GUI champ....I try to keep my examples as simple as Possible...

    ReplyDelete
  3. Thank you for posting! Just a suggestion: since the different Command(s) delegate on the concrete Soldier implementations through its interface, it seems there should be only one concrete Command (all of them do the same thing). I think it would be better if you include some specific behaviour in the concrete implementations of the Command interface.
    Cheers!

    ReplyDelete
  4. Dude,

    Very bad example. There is no UNDO action to firing missiles or killing people.

    ReplyDelete
  5. I guess people are more hurt by this example...its a bit violent.... Apologies for that..

    You are correct in stating that there is no UNDO action if a gun is fired...Here i didn't wanted to reverse the action we fired but only to stop it....
    We can anyways relate to UNDO actions with some other examples....

    ReplyDelete
  6. Seriously, worst theme ever used for a coding example!

    ReplyDelete