1.意图:将一个请求封装为一个对象,从而使得可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
2.结构
Command声明执行操作的接口。
ConcreteCommand将一个接收者对象绑定于一个动作;调用接收者相应的操作,以实现Execute。
Client创建iyge具体命令对象并设定它的接收者。
Invoker要求该命令执行这个请求。
Receiver知道如何实施于执行一个请求相关的操作。任何类都可能作为一个接收者。
3.适用性:
抽象出待执行的动作以参数化某对象。Command模式时过程语言中的回调(Callback)机制的一个面向对象的替代品。
在不同的时刻指定、排列和执行请求。一个Command对象可以有一个于初始请求无关的生存期。如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可以将负责该请求的命令对象传递给另一个不同的进程并在那儿实现该请求。
支持取消操作。Command的Execute操作可在实施操作前将状态存储起来,在取消操作时这个状态用来消除该操作的影响。Command接口必须添加一个Unexecute操作,该操作取消上一次Execute调用的效果。执行的命令被存储在一个历史列表中。可通过向后和向前遍历这一列表并分别调用Unexecute和Execute来实现重数不限的”取消“和”重做“。
支持修改日志。这样当系统奔溃时,这些修改可以被重做一遍。在Command接口中添加装载操作和存储操作,可以用来保持变动的一个一致的修改日志。从奔溃中恢复的过程包括从磁盘中重新读入记录下来的命令并用Execute操作重新执行它们。
用构建在原语操作上的高层操作构建一个系统。这样一种结构在支持事务(Transaction)的信息系统中很常见。Command模式提供了对十五进行建模的方法。Command有一个公共接口,使得可以用同一种方式调用所有的事务,同时使用该模式也易于添加新事务以扩展系统。
4.常见案例:开灯关灯,不同房间同样的操作命令
代码案例:
某灯具厂商预生产一个灯具遥控器,该遥控器具有7个可编辑的捏槽,每个捏槽都有开关灯具的开关,现采用Command(命令)模式实现该遥控器的软件部分。。
软件设计师考试2014年下半年下午题第6题
class Light{
private String name;
public Light(){}
public Light(String name){
this.name = name;
}
public void on(){
System.out.println(name+"开灯");
}
public void off(){
System.out.println(name+"关灯");
}
}
public interface Command {
void execute();
}
class LightOnCommand implements Command{
Light light;
public LightOnCommand(Light light){
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
class LightOffCommand implements Command{
Light light;
public LightOffCommand(Light light){
this.light = light;
}
@Override
public void execute() {
light.off();
}
}
class RemoteControl{
//遥控器
Command[] onCommands = new Command[7];
Command[] offCommands = new Command[7];
public RemoteControl(){}
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();
}
}
class RemoteLoader{
public static void main(String[] args) {
RemoteControl remoteControl = new RemoteControl();
Light livingRoomLight = new Light("Living Room");
Light kitchenLight = new Light("kitchen");
LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight);
LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight);
remoteControl.setCommand(0,livingRoomLightOn,livingRoomLightOff);
remoteControl.setCommand(1,kitchenLightOn,kitchenLightOff);
remoteControl.onButtonWasPushed(0);
remoteControl.offButtonWasPushed(0);
remoteControl.onButtonWasPushed(1);
remoteControl.offButtonWasPushed(1);
}
}
运行结果: