关于 gof-command
gof-command 是讲解 Command 设计模式的技能:将请求表示为对象,使触发操作的一方与具体处理分离。内容涵盖执行、可选撤销、排队、调度和组合,并提供适用判断建议。
主要功能
- 01将请求封装为对象
- 02分离调用方与接收方
- 03支持执行和可选撤销
- 04将命令组合为宏
- 05适用判断建议与反模式
适用场景
- 01分离 UI 操作与具体实现
- 02对操作进行排队或调度
- 03添加撤销与重做行为
- 04记录并执行一系列操作
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ yonatankarp/ software-design-skills --skill gof-command安装后在 Claude Code 中输入/gof-command确认已加载。
详细介绍
一句话概述
将请求封装为对象——把谁触发操作与要做什么分离——以便对请求进行参数化、排队、记录、撤销或组合。
何时使用此技能
- 调用者(UI 按钮、调度器、队列处理器)必须触发操作,但不应知道操作的具体内容。
- 操作需要排队、安排计划、重试或记录。
- 撤销/重做功能:每条命令都知道如何执行和取消自身。
- 构建宏录制器——由一组命令组成并按顺序执行的命令。
- 解耦“应该发生什么”与“实际发生的时间”。
何时不要使用此技能
- 直接调用方法就足够,且无需解耦。
- “命令”只是一个没有参数且没有生命周期的函数——那只是一个函数引用。
- 系统已有处理此问题的作业队列/消息总线。
核心内容
命令将以下内容封装在一起:
- 接收者(执行操作的对象)。
- 操作(要调用的操作)。
- 参数(操作所需的任何数据)。
调用者持有命令引用,并调用 execute(),而无需了解命令的内部实现。具体命令实现 execute(),并可选择实现 undo()。
经典示例:电视遥控器上的每个按钮都持有一条命令。遥控器不知道按钮是开灯、打开车库门,还是启动音响——每个按钮只需对其命令调用 execute()。
组合:MacroCommand 持有一组 Command,并按顺序执行。撤销宏时,顺序反转。
判断依据
- 如果需要撤销/重做,Command 是首选方案。
- 如果需要安排操作、重试操作或远程执行操作,Command 是自然的传输单元。
- 每条 Command 都应当简短且用途明确。大型多步骤命令应放入
MacroCommand。 - 如果
execute()和undo()必须维护先前状态才能完成撤销,Command 必须在执行时捕获该状态(备忘录风格)。
反模式
- 会修改全局状态却没有
undo()的命令——这会使该模式失去主要价值。 - 只有
execute()、没有其他存在理由的命令类——用函数引用即可。 - 在 Command 中编写业务逻辑,而不是委托给接收者——Command 是请求,不是实现。
- “只用一个带类型代码分支的万能 GodCommand”——这是藏在 Command 类中的简单工厂;应将不同变体拆分为独立的命令类型。
另请参阅
gof-strategy— 两者都会封装行为,但 Strategy 用于替换算法;Command 用于对请求排队/安排计划/撤销请求。gof-observer— 命令由事件触发时使用。gof-kotlin-idioms— Kotlin 函数类型(() -> Unit)和 Lambda 表达式无需接口即可覆盖最简单的 Command 场景。
参考资料
- Head First Design Patterns(第 2 版),第 6 章(“封装调用:命令模式”)——经典阐述,以可编程家用遥控器为例。
评论
支持 Markdown