Command Design Pattern

Command design pattern is used to encapsulate a request as an object and pass to an invoker, wherein the invoker does not knows how to service the request but uses the encapsulated command to perform an action.

To understand command design pattern we should understand the associated key terms like client, command, command implementation, invoker, receiver.

Command is an interface with execute method. It is the core of contract.
A client creates an instance of a command implementation and associates it with a receiver.
An invoker instructs the command to perform an action.
A Command implementation’s instance creates a binding between the receiver and an action.
Receiver is the object that knows the actual steps to perform the action.

Command Pattern Discussion

It will be easier to understand all the above with an example. Let us think of developing a universal remote. Our UnversalRemote will have only two buttons, one is to power on and another is to mute all associated ConsumerElectronics.

For ConsumerElectronics we will have couple of implementations Television and SoundSystem. Button is a class that is the invoker of an action.

OnCommand is used to switch on a ConsumerElectronics. While instantaiting OnCommand client needs to set the receiver. Here receiver is either Television or SoundSystem. UniversalRemote class will maintain all the receivers and will provide a method to identify the currently active receiver.

When an instance of a invoker is created, a concrete command is passed to it. Invoker does not know how to perform an action. All it does is honoring the agreement with the Command. Invoker calls the execute() method of the set concrete command.
Command Pattern Example Implementation
Command.java

package com.javahunter.taher.command;
 
public interface Command {
 
  public abstract void execute();
 
}

OnCommand.java

package com.javahunter.taher.command;
 
public class OnCommand implements Command {
 
  private ConsumerElectronics ce;
 
  public OnCommand(ConsumerElectronics ce) {
    this.ce = ce;
  }
 
  public void execute() {
    ce.on();
  }
}

MuteAllCommand.java

package com.javahunter.taher.command;
 
import java.util.List;
 
public class MuteAllCommand implements Command {
  List<ConsumerElectronics> ceList;
 
  public MuteAllCommand(List<ConsumerElectronics> ceList) {
    this.ceList = ceList;
  }
 
  @Override
  public void execute() {
 
    for (ConsumerElectronics ce : ceList) {
      ce.mute();
    }
 
  }
}
ConsumerElectronics.java

package com.javahunter.taher.command;
 
public interface ConsumerElectronics {
  public abstract void on();
  public abstract void mute();
}

Television.java

package com.javahunter.taher.command;
 
public class Television implements ConsumerElectronics {
 
  public void on() {
    System.out.println("Television is on!");
  }
 
  @Override
  public void mute() {
    System.out.println("Television is muted!");
 
  }
}

SoundSystem.java

package com.javahunter.taher.command;
 
public class SoundSystem implements ConsumerElectronics {
 
  public void on() {
    System.out.println("Sound system is on!");
  }
 
  @Override
  public void mute() {
    System.out.println("Sound system is muted!");
 
  }
}

Button.java

package com.javahunter.taher.command;
 
public class Button {
  Command c;
 
  public Button(Command c) {
    this.c = c;
  }
 
  public void click(){
    c.execute();
  }
}

UniversalRemote.java

package com.javahunter.taher.command;
 
public class UniversalRemote {
 
  public static ConsumerElectronics getActiveDevice() {
    // here we will have a complex electronic circuit 🙂
    // that will maintain current device
    Television tv = new Television();
    return tv;
  }
 
}

DemoCommandPattern.java

package com.javahunter.taher.command;
 
import java.util.ArrayList;
import java.util.List;
 
public class DemoCommandPattern {
  public static void main(String args[]) {
 
    // OnCommand is instantiated based on active device supplied by Remote
    ConsumerElectronics ce = UniversalRemote.getActiveDevice();
    OnCommand onCommand = new OnCommand(ce);
    Button onButton = new Button(onCommand);
    onButton.click();
 
    Television tv = new Television();
    SoundSystem ss = new SoundSystem();
    List<ConsumerElectronics> all = new ArrayList<ConsumerElectronics>();
    all.add(tv);
    all.add(ss);
    MuteAllCommand muteAll = new MuteAllCommand(all);
    Button muteAllButton = new Button(muteAll);
    muteAllButton.click();
 
  }
}

Important Points on Command Pattern

Command pattern helps to decouple the invoker and the receiver. Receiver is the one which knows how to perform an action.
Command helps to implement call back in java.
Helps in terms of extensibility as we can add new command without changing existing code.
Command defines the binding between receiver and action.
A command should be able to implement undo and redo operations. That is restting the state of the receiver. It can be done from the support of receiver.

Advertisements
This entry was posted in Core JAVA, Design Pattern and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s