其他
当需要撤销/重做、队列化操作或解耦调用者与执行者时…
在 JavaScript/TypeScript 中,当需要 undo/redo、排队执行或解耦调用方与执行方时,把每个操作封装成带 execute 方法的命令对象。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 54/100 ×0.15
适用场景
当需要撤销/重做、队列化操作或解耦调用者通用
解决思路
- 创建一个 Command 类,其构造函数接收一个 execute 函数并赋值给 this.execute,用它将具体动作封装起来
- 创建一个 Manager 类(如 OrderManager),只保留一个 execute(command, ...args) 方法,内部调用 command.execute(this.orders, ...args),把共享状态(如 orders)作为第一个参数传给命令
- 用命令对象替代 manager 上的直接方法调用:不再调用 manager.placeOrder(...)、manager.trackOrder(...),而是把命令对象传给 manager 的单一 execute 方法
- 为每个操作编写独立的命令工厂函数,并传入需要的参数:PlaceOrderCommand(order, id) 返回 new Command((orders) => { orders.push(id); return `You have successfully ordered ${order} (${id})` })
- CancelOrderCommand(id) 返回 new Command((orders) => { const index = orders.indexOf(id); if (index > -1) orders.splice(index, 1); return `You have canceled your order ${id}` })
- TrackOrderCommand(id) 返回 new Command(() => `Your order ${id} will arrive in 20 minutes.`)
- 通过这次重构,把 placeOrder、cancelOrder、trackOrder 等方法与 manager 对象解耦,变成可通过 execute 调用的独立函数,日后重命名方法(如 placeOrder 改为 addOrder)时无需在代码库中逐处查找旧方法名
- 谨慎克制地使用该模式,因为它会给较简单的 JavaScript 应用带来不必要的样板代码
适用边界 · 注意事项
- 简单的一次性操作,不需要 undo/redo、排队或日志
- 直接用函数调用已经足够清晰,额外抽象只会增加复杂度而无收益
- 系统操作很少,引入命令基础设施属于过度设计