命令模式(Command Pattern)是一种行为设计模式,它将请求封装为一个对象,从而使你可以用不同的请求、队列或者日志来参数化对象。命令模式允许请求的发送者与接收者完全解耦。
关键组成部分
-
Command(命令接口)
定义执行命令的接口,通常包括一个 execute() 方法。 -
ConcreteCommand(具体命令类)
实现 Command 接口,负责调用接收者的相关操作。
它将一个接收者对象绑定到具体的操作上,并通过调用接收者的方法执行请求。 -
Receiver(接收者)
执行具体操作的类。命令执行时,会调用接收者的操作。 -
Invoker(调用者)
持有命令对象,负责调用命令的 execute() 方法。 -
Client(客户端)
创建具体命令对象并设置其接收者,然后将命令传递给调用者。
使用场景
- 请求解耦:当需要将请求的发送者与接收者解耦时。
- 操作记录:需要支持操作的撤销与重做功能。
- 宏命令:需要组合多个操作作为一个整体执行。
示例代码
以下是一个简单的 Java 实现:
// Command 接口
interface Command {void execute();
}// Receiver 接收者
class Light {public void turnOn() {System.out.println("The light is ON");}public void turnOff() {System.out.println("The light is OFF");}
}// ConcreteCommand 实现具体命令
class TurnOnLightCommand implements Command {private Light light;public TurnOnLightCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOn();}
}class TurnOffLightCommand implements Command {private Light light;public TurnOffLightCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.turnOff();}
}// Invoker 调用者
class RemoteControl {private Command command;public void setCommand(Command command) {this.command = command;}public void pressButton() {command.execute();}
}// Client 客户端
public class CommandPatternDemo {public static void main(String[] args) {Light light = new Light();Command turnOn = new TurnOnLightCommand(light);Command turnOff = new TurnOffLightCommand(light);RemoteControl remote = new RemoteControl();// 开灯remote.setCommand(turnOn);remote.pressButton();// 关灯remote.setCommand(turnOff);remote.pressButton();}
}
优缺点
- 优点
解耦:请求发送者和接收者分离。
灵活扩展:可以很容易地增加新的命令类型。
支持撤销和重做:通过记录命令历史实现。 - 缺点
类数量增加:每个命令都需要一个类,可能导致系统复杂度上升。
系统开销:对于简单操作,命令模式显得较为繁琐。
常见应用
事务脚本:数据库操作、日志记录等。
GUI 按钮操作:每个按钮的点击都可以绑定一个命令。
任务队列:任务调度和异步处理。