命令模式
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。支持可撤销操作。
命令可以将不同运算块打包,许久之后,运算依然可以被调用。衍生一些应用,如:Scheduler、线程池、工作队列等。
日志请求:将动命令作记录到日志中,系统死机后可以通过重新调用这些动作恢复到之前的状态。
主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
何时使用:在某些场合,比如要对行为进行”记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将”行为请求者”与”行为实现者”解耦?将一组行为抽象为对象,可
优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。
缺点:使用命令模式可能会导致某些系统有过多的具体命令类。
家电遥控器举例:
public class Light {
String name;
public Light() {
this.name = "Light";
}
public Light(String name) {
super();
this.name = name;
}
public void on() {
System.out.println(name + " is oning");
}
public void off() {
System.out.println(name + " is off");
}
}
public class GarageDoor {
String name;
public GarageDoor() {
this.name = "Garage Door";
}
public GarageDoor(String name) {
super();
this.name = name;
}
public void open() {
System.out.println("Garage Door is Open");
}
public void close() {
System.out.println("Garage Door is close");
}
}
public interface Command {
public void execute();
public void undo();
}
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light) {
super();
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
public class LightOffCommand implements Command {
Light light;
public LightOffCommand(Light light) {
super();
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
public class GarageDoorOpenCommand implements Command {
GarageDoor door;
public GarageDoorOpenCommand(GarageDoor door) {
this.door = door;
}
@Override
public void execute() {
door.open();
}
@Override
public void undo() {
door.close();
}
}
public class GarageDoorCloseCommand implements Command {
GarageDoor door;
public GarageDoorCloseCommand(GarageDoor door) {
this.door = door;
}
@Override
public void execute() {
door.close();
}
@Override
public void undo() {
door.open();
}
}
//控制多个开关命令
public class MacroCommand implements Command {
Command[] commands;
public MacroCommand(Command[] commands) {
this.commands = commands;
}
@Override
public void execute() {
for(Command command: commands){
command.execute();
}
}
@Override
public void undo() {
for(Command command: commands){
command.undo();
}
}
}
public class NoCommand implements Command {
@Override
public void execute() {
}
@Override
public void undo() {
}
}
public class SimpleRemoteControl {
Command slot;
public void setCommand(Command slot) {
this.slot = slot;
}
public void buttonWasPressed(){
slot.execute();
}
}
/**
* 遥控器
*/
public class RemoteControl {
Command[] onCommands;
Command[] offCommands;
Command undoCommand;
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;
}
undoCommand = noCommand;
}
public void setCommand(int slot, Command onCommand, Command offCommand){
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void onButtonWasPress(int slot){
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
public void offButtonWasPress(int slot){
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
public void undoButtonWasPushed(){
undoCommand.undo();
}
@Override
public String toString(){
StringBuffer buffer = new StringBuffer();
buffer.append("\n-----romote Control---------\n");
for(int i=0; i<onCommands.length; i++){
buffer.append("[slot " + i + "] " + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
return buffer.toString();
}
}
public class RemoteControlTest {
public static void main(String[] args) {
SimpleRemoteControl remote = new SimpleRemoteControl();
Light light = new Light();
LightOnCommand lightOn = new LightOnCommand(light);
remote.setCommand(lightOn);
remote.buttonWasPressed();
}
}
public class RemoteLoader {
public static void main(String[] args) {
RemoteControl remoteControl = new RemoteControl();
Light livingRoomLight = new Light("Living room light");
Light kitchenLight = new Light("Kitchen light");
GarageDoor garageDoor = new GarageDoor();
LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight);
LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight);
GarageDoorOpenCommand garageDoorOpen = new GarageDoorOpenCommand(garageDoor);
GarageDoorCloseCommand garageDoorclose = new GarageDoorCloseCommand(garageDoor);
Command[] partyOn = {livingRoomLightOn, kitchenLightOn, garageDoorOpen};
Command[] partyOff = {livingRoomLightOff, kitchenLightOff, garageDoorclose};
//总控开启所有电器
MacroCommand partyOnMacro = new MacroCommand(partyOn);
//总控关闭所有电器
MacroCommand partyOffMacro = new MacroCommand(partyOff);
remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);
remoteControl.setCommand(1, kitchenLightOn, kitchenLightOff);
remoteControl.setCommand(2, garageDoorOpen, garageDoorclose);
remoteControl.setCommand(6, partyOnMacro, partyOffMacro);
System.out.println(remoteControl);
remoteControl.onButtonWasPress(0);
remoteControl.offButtonWasPress(0);
remoteControl.onButtonWasPress(1);
remoteControl.offButtonWasPress(1);
remoteControl.onButtonWasPress(2);
remoteControl.offButtonWasPress(2);
remoteControl.undoButtonWasPushed();
System.out.println("\n=========open all=========");
remoteControl.onButtonWasPress(6);
System.out.println("\n=========close all=========");
remoteControl.offButtonWasPress(6);
System.out.println("\n=========undo all=========");
remoteControl.undoButtonWasPushed();
}
}