为什么80%的码农都做不了架构师?>>>
命令模式:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
四种角色:
Command:定义命令的统一接口
ConcreteCommand:Command接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。
Receiver:命令的实际执行者
Invoker:命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。
一个命令对象通过在特定接收者上绑定一组动作来封装一个请求。命令对象将动作和接收者包进对象中。这个对象只暴露出一个execute()方法,当此方法被调用的时候,接收者就会进行这些动作。从外面来看,其他队形不知道究竟哪个接收者进行了哪些动作,只知道如果调用execute()方法,请求的目的就能达到。
举个栗子:
要实现一个智能开关的遥控器,可以控制客厅和卧室的灯、电视的开关等功能。
定义命令接口:
public interface Command {public void execute();
}
实现灯的开关命令:
// 开灯命令
public class LightOnCommand implements Command {Light light;public LightOnCommand(Light light){this.light = light;}public void execute() {light.on();}
}// 关灯命令
public class LightOffCommand implements Command {Light light;public LightOffCommand(Light light){this.light = light;}public void execute() {light.off();}
}
遥控器:
// 遥控器有七个开关,初始化都是无命令的
public class RemoteControl {Command[] onCommands;Command[] offCommands;// 初始化遥控器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 index, Command onCommand, Command offCommand) {onCommands[index] = onCommand;offCommands[index] = offCommand;}// 按下开按钮public void onButtonWasPushed(int index) {onCommands[index].execute();}// 按下关按钮public void offButtonWasPushed(int index) {onCommands[index].execute();}
}
测试遥控器:
public class RemoteTest {RemoteControl remoteControl = new RemoteControl();Light livingRoomLight = new Light("Living Room");Light kitchenLight = new Light("kitchen");// 设置遥控器按钮命令LightOnCommand livingRoomLightOnCommand = new LightOnCommand(livingRoomLight);LightOffCommand livingRoomLightOffCommand = new LightOffCommand(livingRoomLight);LightOnCommand kitchenLightOnCommand = new LightOnCommand(kitchenLight);LightOffCommand kitchenLightOffCommand = new LightOffCommand(kitchenLight);remoteControl.setCommand(0, livingRoomLightOnCommand, livingRoomLightOffCommand);remoteControl.setCommand(1, kitchenLightOnCommand, kitchenLightOffCommand);// 卧室灯开关操作remoteControl.onButtonWasPushed(0);remoteControl.offButtonWasPushed(0);// 厨房灯开关操作remoteControl.onButtonWasPushed(1);remoteControl.offButtonWasPushed(1);
}