一,命令模式
命令模式:
- 在系统设计中,经常需要向某些对象发送请求,但可能并不知道请求的接受者是谁,也不知道被请求的操作是哪个,我们只需要在程序运行时指定具体的请求接收者即可,此时就可以使用命令模式来设计;
- 命令模式使得请求接收者与发送者之间解耦,让对象之间的调用更加灵活;
- 在命令模式中,会将一个请求封装为一个对象,使用不同参数来表示不同的请求,且命令必须支持可撤销;
二,原理类图
意图: 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
适用性:
- 抽象出待执行的动作以参数化某对象,你可用过程语言中的回调(call back)函数表达这种参数化机制。所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。Command 模式是回调机制的一个面向对象的替代品。
- 在不同的时刻指定、排列和执行请求。一个Command对象可以有一个与初始请求无关的生存期。如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可将负责该请求的命令对象传送给另一个不同的进程并在那儿实现该请求。
- 支持取消操作。Command的Excute 操作可在实施操作前将状态存储起来,在取消操作时这个状态用来消除该操作的影响。Command 接口必须添加一个Unexecute操作,该操作取消上一次Execute调用的效果。执行的命令被存储在一个历史列表中。可通过向后和向前遍历这一列表并分别调用Unexecute和Execute来实现重数不限的“取消”和“重做”。
- 支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。在Command接口中添加装载操作和存储操作,可以用来保持变动的一个一致的修改日志。从崩溃中恢复的过程包括从磁盘中重新读入记录下来的命令并用Execute操作重新执行它们。
- 用构建在原语操作上的高层操作构造一个系统。这样一种结构在支持事务( transaction)的信息系统中很常见。一个事务封装了对数据的一组变动。Command模式提供了对事务进行建模的方法。Command有一个公共的接口,使得你可以用同一种方式调用所有的事务。同时使用该模式也易于添加新事务以扩展系统。
三,实例
Invoke(调用者)
package com.neei.command;
/**
* @param
* @Author: AaNeei
* @Date: 2019/10/13 21:53
* @Description: 游学网
* @throws:
*/
public class RemoteController {
Command[] onCommands;
Command[] offCommands;
//负责撤销
Command undoCommand;
public RemoteController() {
onCommands = new Command[5];
offCommands = new Command[5];
for (int i = 0; i < 5; i++) {
//初始化
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
}
//设置需要的命令
public void setCommand(int no, Command onCommand, Command offCommand) {
onCommands[no] = onCommand;
offCommands[no] = offCommand;
}
//按下开
public void onPushed(int on) {
onCommands[on].execute();
//用于记录当前按钮,用于撤销
undoCommand = onCommands[on];
}
//按下关
public void offPushed(int on) {
offCommands[on].execute();
//用于记录当前按钮,用于撤销
undoCommand = offCommands[on];
}
//撤销
public void undoPushed() {
undoCommand.undo();
}
}
Command(命令)
package com.neei.command;
/**
* @param
* @Author: AaNeei
* @Date: 2019/10/13 21:43
* @Description: 游学网
* @throws:
*/
public interface Command {
//操作
void execute();