Command(命令)模式是一种行为设计模式,它将请求封装成一个对象,从而让你可以用不同的请求对客户进行参数化、对请求排队或记录请求日志,以及支持可撤销的操作。
核心思想
-
将请求封装为对象:将操作(如方法调用)封装成独立的对象。
-
解耦调用者和接收者:调用者不需要知道接收者的具体实现。
-
支持扩展:可以轻松添加新的命令,而无需修改现有代码。
主要角色
-
Command(命令接口):声明执行操作的接口。
-
ConcreteCommand(具体命令):实现命令接口,绑定接收者和动作。
-
Invoker(调用者):要求命令执行请求。
-
Receiver(接收者):知道如何执行与请求相关的操作。
-
Client(客户端):创建具体命令并设置接收者。
使用Command模式模拟一个智能家居遥控器系统
首先定义一个command接口
// 1. Command 接口
interface Command {
void execute();
void undo(); // 支持撤销操作
}
然后定义俩个接收者(receive)
// 2. Receiver(接收者):灯
class Light {
public void on() {
System.out.println("Light is ON");
}
public void off() {
System.out.println("Light is OFF");
}
}
// 3. Receiver(接收者):风扇
class Fan {
public void on() {
System.out.println("Fan is ON");
}
public void off() {
System.out.println("Fan is OFF");
}
}
开灯关灯指令和开风扇和开风扇指令类
// 4. ConcreteCommand:开灯命令
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
// 5. ConcreteCommand:关灯命令
class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
// 6. ConcreteCommand:开风扇命令
class FanOnCommand implements Command {
private Fan fan;
public FanOnCommand(Fan fan) {
this.fan = fan;
}
@Override
public void execute() {
fan.on();
}
@Override
public void undo() {
fan.off();
}
}
最后写一个调用者
// 7. Invoker(调用者):遥控器
class RemoteControl {
private List<Command> commandHistory = new ArrayList<>();
public void executeCommand(Command command) {
command.execute();
commandHistory.add(command); // 记录历史用于撤销
}
public void undoLastCommand() {
if (!commandHistory.isEmpty()) {
Command lastCommand = commandHistory.remove(commandHistory.size() - 1);
lastCommand.undo();
}
}
}
现在基本的基础就写好了,直接开启测试
// 8. Client(客户端)
public class CommandPatternDemo {
public static void main(String[] args) {
// 创建接收者
Light livingRoomLight = new Light();
Fan ceilingFan = new Fan();
// 创建具体命令
Command lightOn = new LightOnCommand(livingRoomLight);
Command lightOff = new LightOffCommand(livingRoomLight);
Command fanOn = new FanOnCommand(ceilingFan);
// 创建调用者
RemoteControl remote = new RemoteControl();
// 执行命令
remote.executeCommand(lightOn); // 开灯
remote.executeCommand(fanOn); // 开风扇
remote.executeCommand(lightOff); // 关灯
System.out.println("\n--- Undoing last command ---");
remote.undoLastCommand(); // 撤销关灯(灯会重新打开)
}
}
此时得到输出
模式优势
-
解耦:调用者(遥控器)与接收者(灯/风扇)完全解耦。
-
可扩展:添加新设备只需新增 Command 类,无需修改现有代码。
-
支持撤销:通过维护命令历史实现撤销功能。
-
支持宏命令:可以轻松组合多个命令(如"回家模式"=开灯+开风扇)。
实际应用场景
-
GUI 的按钮/菜单操作
-
事务管理(支持回滚)
-
任务队列系统
-
游戏中的输入处理