Command Design Pattern (TAKE TWO!)

overview

DEFINITION

  • IS A BEHAVIORAL DESIGN PATTERN

  • turns a request into a stand-alone object that contains all information about the request

  • parameterize methods with different requests, delay or queue a request’s execution

  • support undoable operations

PLAIN WORDS

Allows you to encapsulate actions in objects. The key idea behind this pattern is to provide the means to decouple client from receiver.

Concept / analogy

ordering food at a restaurant:
You (i.e.
Client) ask the waiter (i.e. Invoker) to bring some food (i.e. Command) and waiter simply forwards the request to Chef (i.e. Receiver) who has the knowledge of what and how to cook.

lets say We want to program a remote control api

but we have so many diff vendor classes with diff operations

The STATEMENT Problem 1

Business Logic & User Interface Layer is tightly coupled together

The STATEMENT Problem 2

Some operations may have different parameters

The STATEMENT Problem 3

Some operations can be invoked from different places

Structure explaination

The Customer

The Waiter

The Order

The Order

The Chef

with command pattern, we encapsulate each operation into a command

Device (Receiver) will react to the invoked command

Command can be assigned to a particular slot (invoker)

the remote control

public class RemoteControl {

      Command[] onCommands;
      Command[] offCommands;
      
      // initialize emtpy commands in all slots
      public RemoteControl() {
            onCommands = new Command[7];
            offCommands = new Command[7];
            
            Command noCommand = new NoCommand();
            for(int i=0; i<7; i++) {
                  onCommands[i] = noCommand;
                  offCommands[i] = noCommand;
            }
            
      }
      
      public void setCommand(int slot, Command onCommand, Command offCommand) {
            onCommands[slot] = onCommand;
            offCommands[slot] = offCommand;
      }
      
      public void onButtonWasPushed(int slot) {
            onCommands[slot].execute();
      }
      
      public void offButtonWasPushed(int slot) {
            offCommands[slot].execute();
      }
      
      public String toString() {
            // ommited the implement to print the remote control based on the configurations
      }
}

THE Commands

public interface Command {
      public void execute();
}


public class LightOnCommand implements Command {
      Light light;
      
      public LightOnCommand(Light light) {
            this.light = light;
      }

      
      public void onButtonWasPushed(int slot) {
            light.on();
      }
}

public class LightOffCommand implements Command {
      Light light;
      
      public LightOffCommand(Light light) {
            this.light = light;
      }

      
      public void execute() {
            this.light.off();
      }
}

public class StereoOnWithCDCommand implements Command {
      Stereo stereo;
      
      public StereoOnWithCDCommand(Stereo stereo) {
            this.stereo = stereo;
      }

      
      public void execute() {
            this.stereo.on();
            this.stereo.setCD();
            this.stereo.setVolume(11);
      }
}
public static void main (String[] args) {

      // Create all devices (Receiver) in the proper locations
      Light livingRoomLight = new Light("Living Room");
      Light kitchenLight = new Light("Kitchen");
      CeilingFan ceilingFan = new CeilingFan("Living Room");
      GarageDoor garageDoor = new GarageDoor("");
      Stereo stereo = new Stereo("Living Room");
      
      // Create all Light Commands
      LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
      LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
      LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight);
      LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight);
      
      // Create all On & Off Commands for the ceiling fan
      CeilingFanOnCommand ceilingFanOn = new CeilingFanOnCommand(ceilingFan);
      CeilingFanOffCommand ceilingFanOff = new CeilingFanOffCommand(ceilingFan);
      
      // Create all Up & Down Commands for the garage door
      GarageDoorUpCommand garageDoorUp = new GarageDoorUpCommand(garageDoor);
      GarageDoorDownCommand garageDoorDown = new GarageDoorDownCommand(garageDoor);
      
      // Create all On & Off Commands for the stereo
      StereoOnWithCDCommand stereOnWithCD = new StereoOnWithCDCommand(stereo);
      StereoOffCommand stereOff = new StereoOffCommand(stereo);
      
      // Load all the commands into the remote slots
      RemoteControl remoteControl = new RemoteControl();
      remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);
      remoteControl.setCommand(1, kitchenLightOn, kitchenLightOff);
      remoteControl.setCommand(2, ceilingFanOn, ceilingFanOff);
      remoteControl.setCommand(3, stereoOnWithCD, stereoOff);
      System.out.printlin(remoteControl); // print out the remote control
      
      // press the buttons!
      remoteControl.onButtonWasPushed(0);
      remoteControl.offButtonWasPushed(0);
      remoteControl.onButtonWasPushed(1);
      remoteControl.offButtonWasPushed(1);
      remoteControl.onButtonWasPushed(2);
      remoteControl.offButtonWasPushed(2);
      remoteControl.onButtonWasPushed(3);
      remoteControl.offButtonWasPushed(3);
}

THE CLIENT

Result

Application 1

WHen to use the command pattern

When you want to parametrize objects with operations.

Application 2

WHen to use the command pattern

You want to queue operations, schedule their execution or execute them remotely.

IMPLEMENTING JOB QUEUE

Application 3

WHen to use the command pattern

You want to implement reversible operations.

IMPLEMENTING UNDO

Application 4

WHen to use the command pattern

You want to implement logging of every command executions for auto failover
  • Store a backup on every command execution
  • Load the backup upon any server crashing to restore the state

IMPLEMENTING Auto Failover

references

Kahoot

Command Design Pattern Retake

By Wan Mohd Hafiz

Command Design Pattern Retake

  • 358