命令模式的核心是将请求封装为对象以解耦调用者与执行者,通过统一接口(如execute())实现开闭原则,支持撤销、队列、宏命令等扩展,并要求命令对象在构造时捕获全部上下文以保障封装性。

命令模式的核心是把“请求”变成一个对象,让调用者(Invoker)和执行者(Receiver)解耦。它不是直接调用方法,而是通过封装好的命令对象来中转——这个对象既知道要做什么(绑定接收者和动作),又具备统一的接口(如 execute()),还能支持撤销、排队、日志等扩展。
定义命令接口与具体命令类
先抽象出统一的命令行为,通常是一个无参的 execute() 方法;如果有撤销需求,再加 undo()。每个具体命令类持有对 Receiver 的引用,并在 execute() 中调用其对应方法。
- 命令接口(如
Command)只声明execute(),不涉及具体逻辑 - 具体命令类(如
LightOnCommand)在构造时接收Light实例,execute()内部调用light.turnOn() - Receiver(如
Light)只关心自身业务逻辑,完全 unaware 命令的存在
由调用者触发命令,而非直接操作接收者
Invoker(比如遥控器、按钮或调度器)不依赖任何具体 Receiver 或操作细节,只面向 Command 接口。它拿到命令对象后,只负责调用 execute() —— 至于是开灯、保存文件还是发送邮件,对它透明。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 按钮点击事件可设置为
button.setCommand(new SaveCommand(document)) - 点击时执行
button.onClick()→ 内部调用command.execute() - 同一按钮后续可轻松切换为
NewCommand或PrintCommand,无需改按钮代码
支持扩展:队列、撤销与宏命令
因为请求已变成对象,自然可被存储、传递、组合。例如:
-
撤销:命令对象保存执行前状态(如文本编辑前的内容),
undo()恢复它 -
事务/队列:把多个命令放进列表,由调度器依次
execute(),甚至支持重做 -
宏命令:实现一个
MacroCommand,内部持有一组子命令,execute()遍历调用全部子命令
注意参数与生命周期管理
命令对象应包含执行所需全部上下文。如果操作依赖运行时数据(如用户输入、当前选中项),应在创建命令时捕获,而不是在 execute() 里现场获取——否则会引入隐式依赖,破坏封装性。
- 错误做法:
execute()中调用UI.getSelectedText()—— 命令与 UI 强耦合 - 正确做法:构造命令时传入
selectedText字符串,execute()只操作该字段 - 命令对象通常是一次性或短生命周期的,避免长期持有大对象或资源句柄

















