一、核心定义与目标
命令模式通过对象化请求,将操作的具体实现细节隐藏在命令对象中,使得调用者(Invoker)无需直接与接收者(Receiver)交互,仅需通过命令对象间接调用。这种解耦设计支持以下功能:
- 请求队列化:命令对象可存储、传递并按需执行。
- 撤销与重做:通过记录命令历史实现操作回滚。
- 日志记录与事务支持:便于追踪和恢复系统状态。
二、模式结构与角色
命令模式涉及以下核心角色:
- Command(抽象命令接口)
定义执行命令的统一接口,通常包含execute()
方法。public interface Command { void execute(); }
- ConcreteCommand(具体命令类)
实现Command
接口,持有接收者(Receiver)的引用,并调用其具体方法。public class LightOnCommand implements Command { private Light light; public LightOnCommand(Light light) { this.light = light; } public void execute() { light.turnOn(); } }
- Receiver(接收者)
实际执行操作的对象,例如电灯、音响设备等。public class Light { public void turnOn() { System.out.println("开灯"); } }
- Invoker(调用者)
负责触发命令的执行,但不关心命令的具体实现。public class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); } }
- Client(客户端)
创建具体命令对象并关联接收者,将其传递给调用者。
三、代码示例与实现
场景:遥控器控制电灯
- 定义接收者
class Light { public void on() { System.out.println("灯开启"); } public void off() { System.out.println("灯关闭"); } }
- 实现具体命令
class LightOnCommand implements Command { private Light light; public LightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } }
- 调用者与客户端
结果:通过调用者间接控制接收者,实现解耦。public class Client { public static void main(String[] args) { Light light = new Light(); Command command = new LightOnCommand(light); RemoteControl control = new RemoteControl(); control.setCommand(command); control.pressButton(); // 输出:灯开启 } }
四、高级应用场景
- 宏命令(Macro Command)
将多个命令组合成一个复合命令,例如批量执行操作:class MacroCommand implements Command { private List commands = new ArrayList<>(); public void add(Command cmd) { commands.add(cmd); } public void execute() { commands.forEach(Command::execute); } }
- 撤销与重做(Undo/Redo)
通过扩展命令对象的undo()
方法实现撤销功能:public interface UndoableCommand extends Command { void undo(); }
- 异步命令队列
结合线程池处理异步任务,提升系统吞吐量。
五、优缺点分析
优点 | 缺点 |
---|---|
解耦请求发送者与接收者,提升灵活性 | 可能导致类爆炸问题(每个命令需独立类) |
支持扩展新命令,符合开闭原则 | 增加系统复杂度,需额外管理命令对象 |
便于实现撤销、日志记录等高级功能 | 过度设计风险,简单场景可能不必要 |
六、适用场景
- 需要将请求参数化或延迟执行(如GUI按钮点击)。
- 需支持撤销/重做操作(如文本编辑器)。
- 系统需记录操作日志或实现事务管理。
七、与其他模式的对比
策略模式:关注算法替换,而命令模式关注请求封装。
- 观察者模式:通过订阅-发布机制解耦,而命令模式通过对象化请求解耦。
总结
命令模式通过对象化请求实现了灵活的调用机制,是构建可扩展、可维护系统的利器。但在实际应用中需权衡其复杂性,避免滥用。结合具体场景(如撤销操作、异步任务)选择是否引入该模式,可显著提升代码的解耦性与扩展性。