命令模式(Command)
定义
将**请求(一个动作)**封装成对象(命令对象),使得可以用不同的请求对客户进行参数化。
在命令模式中,"请求"指的是一个特定的操作或动作,即客户端希望调用的功能。这个请求被封装在一个对象中,即命令对象。命令对象包含了执行该请求所需的所有信息,包括调用哪个对象、执行什么方法以及可能需要的参数等。
使用场景
主要角色
- 命令(Command): 命令是一个接口或抽象类,其中定义了执行特定操作的方法。它通常包含一个
execute
方法,该方法在调用时会触发与命令相关的操作。命令的实现类将具体的操作绑定到execute
方法中。 - 具体命令(ConcreteCommand): 具体命令是命令接口的实现类。它关联了一个接收者对象,并实现了
execute
方法,该方法调用接收者的具体操作来完成命令请求。 - 调用者(Invoker): 调用者是负责触发命令执行的对象。它包含一个命令对象,并在某个时刻调用命令的
execute
方法。调用者并不需要了解命令的具体细节,只需知道如何调用命令。 - 接收者(Receiver): 接收者是实际执行命令操作的对象。它知道如何执行具体的操作。命令对象通过调用接收者的方法来实现命令的具体执行。
- 客户端(Client): 客户端是创建和配置命令对象、具体命令对象、调用者以及接收者的地方。客户端负责组装这些对象来创建一个完整的命令模式。
类图
示例代码
java
/**
* 接收者
*/
public class Light {
void turnOn() {
System.out.println("Light is ON");
}
void turnOff() {
System.out.println("Light is OFF");
}
}
java
public interface Command {
void execute();
void undo();
}
java
/**
* 具体命令 开灯
*/
public class LightOnCommand implements Command {
private Light light;
LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
@Override
public void undo() {
light.turnOff();
}
}
java
/**
* 具体命令:关灯
*/
public class LightOffCommand implements Command {
private Light light;
LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
@Override
public void undo() {
light.turnOn();
}
}
java
/**
* 调用者 遥控器
*/
public class RemoteControl {
private Command command;
private List<Command> commandHistory = new ArrayList<>();
void setCommand(Command command) {
this.command = command;
commandHistory.add(command);
}
void pressButton() {
command.execute();
commandHistory.add(command);
}
}
总结
命令模式在调用者和具体的执行者(接受者)之间加了一层(命令层)
优点
- 解耦调用者和接收者: 命令模式将请求封装成独立的对象,使得调用者不需要直接知道接收者的细节。这种解耦可以降低系统中各个模块之间的依赖关系,提高代码的可维护性。
- 支持撤销和重做: 命令模式通过保存命令对象的历史状态,提供了简单的撤销和重做机制。这对于需要支持撤销和重做操作的应用程序是一个很有用的特性。
- 支持事务: 如果命令对象能够包含多个原子操作,那么命令模式可以用于实现事务处理系统。当命令对象被执行时,它们可以一起成功或一起失败。
- 可扩展性: 命令模式允许您轻松添加新的命令类,而无需更改现有的调用者和接收者。这使得系统更加灵活,容易扩展。
- 统一的接口: 命令模式为所有命令提供了统一的接口,这使得调用者无需关心具体的命令类。这种一致性的接口使得系统更易于理解和维护。
- 易与实现宏命令和组合命令
缺点
- 复杂度
- 性能开销
工作中遇到场景
- 文本编辑器(撤销undo与重做redo)
- 图形编辑器(撤销undo与重做redo)
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2klwrba6wi4g4