Sunday, December 30, 2012

Desing Patterns in Java - Command pattern

Description

Command pattern is an object behavioral pattern that allows us to achieve complete decoupling between the sender and the receiver. (A sender is an object that invokes an operation, and a receiver is an object that receives the request to execute a certain operation.

This pattern allows the requester of a particular action to be decoupled from the object that performs the action.

This pattern encodes the details needed to send a message to an object. Such messages can be invoked along different points of time or location in a general way without having to hard-code its details. It allows messages to be invoked one or more times, or passed along to different parts of the system or multiple systems without requiring the details of a specific invocation to be known before execution.

Object references VS function pointers

Some languages (C for example) support function pointers facilities that allow programs to store and transmit the ability to invoke a particular function. Java does not provide function pointers, but object references together with dynamic loading and binding mechanism can be used to achieve a similar effect. This is where command pattern comes into play.

Example

We will use simple remote control for CD Player as example. This simple CD Player support only basic commands (Play, Stop and Pause), but that is good enough for out example of command pattern.

//Cd Player that will be controlled by remote control
public class CdPlayer {

  public enum State {
    PAUSE, PLAY, STOP
  }

  private State state;

  public void pause() {
    state = State.PAUSE;
  }

  public void stop() {
    state = State.STOP;
  }

  public void play() {
    state = State.PLAY;
  }

  public State getState() {
    return state;
  }

}
//Simple command interface.
public interface Command { 
  void execute(); 
}
//Cd Player remote control that will control Cd Player through button press.
public class CdPlayerRemoteControl {
 
  private Command command;
 
  public void setCommand(Command command) {
    this.command = command;
  } 
 
  public void pressButton() {
    command.execute();
  }
}

//Cd Player play command.
public class CdPlayerPlayCommand implements Command {

  private CdPlayer cdPlayer;
 
  public CdPlayerPlayCommand(CdPlayer cdPlayer) {
    this.cdPlayer = cdPlayer;
  }
 
  public void execute() {
    cdPlayer.play();
  }
 
}
//Cd Player pause command.
public class CdPlayerPauseCommand implements Command {

  private CdPlayer cdPlayer;
 
  public CdPlayerPauseCommand(CdPlayer cdPlayer) {
    this.cdPlayer = cdPlayer;
  }
 
  public void execute() {
    cdPlayer.pause();
  }
 
}
//Stop command...
public class CdPlayerStopCommand implements Command {
 
  private CdPlayer cdPlayer;
 
  public CdPlayerStopCommand(CdPlayer cdPlayer) {
    this.cdPlayer = cdPlayer;
  }
 
  public void execute() {
    cdPlayer.stop();
  }
 
}
//Client class that uses remote control for CD Player control.
public class Client {
 
  public static void main(String[] args) {
    CdPlayerRemoteControl cdPlayerRemoteControl = new CdPlayerRemoteControl();  
    CdPlayer cdPlayer = new CdPlayer();
    
    Command play = new CdPlayerPlayCommand(cdPlayer);
    Command pause = new CdPlayerPauseCommand(cdPlayer);
    Command stop = new CdPlayerStopCommand(cdPlayer);
  
    //Play music  
    cdPlayerRemoteControl.setCommand(play);
    cdPlayerRemoteControl.pressButton();
    
    //Stop music
    cdPlayerRemoteControl.setCommand(stop);
    cdPlayerRemoteControl.pressButton();
  
    //prints STOP
    System.out.println(cdPlayer.getState());
  
  }
 
}

1 comment:

  1. We are really grateful for your blog post. You will find a lot of approaches after visiting your post. I was exactly searching for. Thanks for such post and please keep it up. Great work. logo design

    ReplyDelete