命令模式:将请求封装成对象,使你可以用不同的请求对客户进行参数化;对请求排队、记录请求日志,以及支持可撤销操作。 角色:
Command(命令接口):声明执行方法
execute(),撤销undo()ConcreteCommand(具体命令):持有接收者,实现接口
Receiver(接收者):真正执行业务逻辑
Invoker(调用者 / 请求发起者):持有命令对象,触发命令执行,不关心具体实现
Client(客户端):创建具体命令,绑定接收者
完整示例代码
/**
* 命令接口 Command
*/
public interface Command {
// 执行命令
void execute();
// 撤销命令
void undo();
}
/**
* 接收者 Receiver:灯,真正干活的对象
*/
class Light {
public void on() {
System.out.println("✅ 灯打开");
}
public void off() {
System.out.println("❌ 灯关闭");
}
}
/**
* 具体命令:开灯命令
*/
class LightOnCommand implements Command {
private final Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
/**
* 具体命令:关灯命令
*/
class LightOffCommand implements Command {
private final Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
/**
* 空命令:简化调用者判空逻辑,空对象模式
*/
class NoCommand implements Command {
@Override
public void execute() {}
@Override
public void undo() {}
}
/**
* Invoker 调用者:遥控器,持有命令对象,触发执行
*/
class RemoteControl {
private Command slot;
public RemoteControl() {
// 默认赋值空命令,避免null判断
slot = new NoCommand();
}
public void setCommand(Command command) {
this.slot = command;
}
// 按下按钮,执行命令
public void buttonPressed() {
slot.execute();
}
// 撤销按钮
public void undoButtonPressed() {
slot.undo();
}
}
/**
* 客户端测试
*/
public class CommandDemo {
public static void main(String[] args) {
// 1. 创建接收者
Light light = new Light();
// 2. 创建具体命令,绑定接收者
Command lightOn = new LightOnCommand(light);
Command lightOff = new LightOffCommand(light);
// 3. 创建调用者(遥控器)
RemoteControl remote = new RemoteControl();
// 设置开灯命令,按下按钮
remote.setCommand(lightOn);
remote.buttonPressed();
remote.undoButtonPressed();
System.out.println("--------");
// 设置关灯命令
remote.setCommand(lightOff);
remote.buttonPressed();
remote.undoButtonPressed();
}
}
输出结果
✅ 灯打开
❌ 灯关闭
--------
❌ 灯关闭
✅ 灯打开
扩展:支持命令队列(批量执行)
import java.util.ArrayList;
import java.util.List;
class MacroCommand implements Command {
private final List<Command> commandList;
public MacroCommand(List<Command> commandList) {
this.commandList = commandList;
}
@Override
public void execute() {
for (Command cmd : commandList) {
cmd.execute();
}
}
@Override
public void undo() {
// 撤销逆序执行
for (int i = commandList.size() -1; i >=0; i--) {
commandList.get(i).undo();
}
}
}
// 测试宏命令
class MacroTest {
public static void main(String[] args) {
Light light = new Light();
List<Command> cmds = new ArrayList<>();
cmds.add(new LightOnCommand(light));
// 可以追加其他设备命令
MacroCommand macro = new MacroCommand(cmds);
macro.execute();
macro.undo();
}
}
命令模式要点总结
解耦:调用者
Invoker和接收者Receiver完全解耦,调用者只操作 Command 接口。可撤销 undo:命令对象保存状态,支持回滚。
宏命令 Macro:把多个命令组合批量执行。
队列 / 日志:Command 对象可以存入队列、持久化日志,实现任务重放。
空命令 NoCommand:消除大量
if(null)判断。
常见业务场景
任务队列、请求排队
操作撤销 / 回滚
菜单按钮、快捷键
日志记录、命令重放
工作流任务封装
本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
原文链接
欢迎访问