命令模式是一种行为设计模式,将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,命令模式也支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
结构
- Command类:是一个抽象类/接口,类中对需要执行的命令进行声明,一般来说要对外公布一个execute方法用来执行命令。
- ConcreteCommand类:Command类的实现类,对抽象类中声明的方法进行实现。
- Client类:最终的客户端调用类。
- Invoker类:调用者,负责调用命令。
- Receiver类:接收者,负责接收命令并且执行命令。
命令模式的本质是对请求进行封装, 每一个命令都是一个操作,请求方和接收方各自独立,请求一方不必知道接收方的接口和实现。
命令模式的关键在于引入了抽象命令类,请求发送者针对抽象命令类编程,只有实现了抽象命令类的具体命令才与请求接收者相关联。在最简单的抽象命令类中只包含了一个抽象的execute()方法,每个具体命令类将一个Receiver类型的对象作为一个实例变量进行存储,从而具体指定一个请求的接收者,不同的具体命令类提供了execute()方法的不同实现,并调用不同接收者的请求处理方法 – 摘自:gitbook
类图
代码
抽象命令类:
abstract class Command {
public abstract void execute();
}
调用者:针对抽象命令类编程
class Invoker {
private Command command;
//构造注入
public Invoker(Command command) {
this.command = command;
}
//设值注入
public void setCommand(Command command) {
this.command = command;
}
//业务方法,用于调用命令类的execute()方法
public void call() {
command.execute();
}
}
具体命令类:
class ConcreteCommand extends Command {
private Receiver receiver; //维持一个对请求接收者对象的引用
public void execute() {
receiver.action(); //调用请求接收者的业务处理方法action()
}
}
接收者:
class Receiver {
public void action() {
//具体操作
}
}
适用场景
- 如果你想要将操作放入队列中、 操作的执行或者远程执行操作, 可使用命令模式。
- 如果你想要实现操作回滚功能, 可使用命令模式。
优缺点
- 单一职责原则。 你可以解耦触发和执行操作的类。
- 开闭原则。 你可以在不修改已有客户端代码的情况下在程序中创建新的命令。
- 你可以实现撤销和恢复功能。
- 你可以实现操作的延迟执行。
- 你可以将一组简单命令组合成一个复杂命令。
缺点:代码可能会变得更加复杂, 因为你在发送者和接收者之间增加了一个全新的层次。命令可能会膨胀。
总结
- 命令模式是一种对象行为型模式,将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
- 命令模式有缺点,会出现大量具体命令类。