简介
一、定义
1、概念
- 命令(Command)模式:将一个请求封装为一个对象,从而可以用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
- 命令模式是一种对象行为型模式,其别名为动作(Action)模式或事物(Transaction)模式。
2、理解
- 此模式的本质在于:对请求进行封装,一个请求对应一个命令,将发出命令的责任和执行命令的责任分割开,使得请求的一方不必了解接收请求的一方的接口,更不必知道请求如何被接收、操作是否被执行、何时被执行,以及是怎么被执行的
二、组件
- Command(抽象命令类):抽象命令类一般是一个抽象类或接口,在其中声明了用于执行请求的execute()等方法,通过这些方法可以调用请求接收者的相关操作。
- ConcreteCommand(具体命令类):具体命令类是抽象命令类的子类,实现了在抽象命令类中声明的方法,在实现execute()方法时,将调用接收者对象的相关操作(Action)。
- Invoker(调用者):即请求发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联关系。在程序运行时可以将一个具体命令对象注入其中,再调用具体命令对象的execute()方法,从而实现间接调用请求接收者的相关操作。
- Receiver(接收者):接收者执行与请求相关的操作,它具体实现对请求的业务处理。
三、结构图
示例
一、抽象 & 具体命令类
abstract class Command {
public abstract void execute();
}
class ConcreteCommand extends Command {
private Receiver receiver;
public void execute() {
receiver.action();
}
}
二、请求发送者 & 接受者
class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
public void call() {
command.execute();
}
}
class Receiver {
public void action() {
}
}
总结
一、优缺点
1、优点
- 降低了系统的耦合度 => 请求发送者与接受者不存在直接引用
- 方便地增加新的命令到系统中 => 无须修改源代码,从而符合开闭原则
2、缺点
二、使用场景
三、命令队列 & 撤销操作 & 宏命令
1、命令队列
- 就是维护一个 command 的列表,请求调用者和这个命令的列表产生关系二不再是单一的命令,遍历该列表即可实现对个接受者的调用
class CommandQueue {
private ArrayList<Command> commands = new ArrayList<Command>();
public void addCommand(Command command) {
commands.add(command);
}
public void removeCommand(Command command) {
commands.remove(command);
}
public void execute() {
for (Object command : commands) {
((Command)command).execute();
}
}
}
2、撤销操作(undo方法)
- 通过一个 逆向操作 来实现撤销
- 还可以通过 保存对象的历史状态 来实现撤销
3、宏命令(和命令队列有点像)
- 宏命令(Macro Command)又称为组合命令,它是组合模式和命令模式联用的产物
- 宏命令是一个具体命令类,有一个包含了对其他命令对象的引用的集合属性
- 通常宏命令不直接与请求接收者交互,而是通过它的成员来调用接收者的方法
- 执行一个宏命令将触发多个具体命令的执行,从而实现对命令的批处理
参考文章
java设计模式之命令模式
设计模式的征途—19.命令(Command)模式