Allows you to encapsulate actions in objects. The key idea behind this pattern is to provide the means to decouple client from receiver.
Business Logic & User Interface Layer is tightly coupled together
Some operations may have different parameters
Some operations can be invoked from different places
The Customer
The Waiter
The Order
The Order
The Chef
Device (Receiver) will react to the invoked command
Command can be assigned to a particular slot (invoker)
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
}
}
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);
}
When you want to parametrize objects with operations.
You want to queue operations, schedule their execution or execute them remotely.
You want to implement reversible operations.
You want to implement logging of every command executions for auto failover