共计 2000 个字符,预计需要花费 5 分钟才能阅读完成。
Command(命令模式)
Command(命令模式)属于行为型模式。
用意:将一个申请封装为一个对象,从而使你可用不同的申请对客户进行参数化,对申请排队或记录申请日志,以及反对可撤销的操作。
举例子
如果看不懂下面的用意介绍,没有关系,设计模式须要在日常工作里用起来,联合例子能够加深你的了解,上面我筹备了三个例子,让你领会什么场景下会用到这种设计模式。
点菜是命令模式
为什么顾客会找服务员点菜,而不是间接冲到后厨盯着厨师做菜?因为做菜比较慢,必定会呈现排队的景象,而且有些菜可能是一起做效率更高,所以将点菜和做菜拆散比拟容易管制整体效率。
其实这个社会景象就对应编程畛域的命令模式:点菜就是一个个申请,点菜员记录的菜单就是将申请生成的对象,点菜员不须要关怀怎么做菜、谁来做,他只有把菜单传到后厨即可,由后厨对立调度。
大型软件系统的操作菜单
大型软件操作系统都有一个特点,即软件非常复杂,菜单按钮十分多。但因为菜单按钮自身并没有业务逻辑,所以通过菜单按钮点击后触发的业务行为不适宜由菜单按钮实现,此时可利用命令模式生成一个或一系列指令,由软件系统的实现局部来真正执行。
浏览器申请排队
浏览器的申请不仅会排队,还会勾销、重试,因而是个典型的命令模式场景。如果不能将 window.fetch
序列化为一个个指令放入到队列中,是无奈实现申请排队、勾销、重试的。
用意解释
用意:将一个申请封装为一个对象,从而使你可用不同的申请对客户进行参数化,对申请排队或记录申请日志,以及反对可撤销的操作。
一个申请指的是来自客户端的一个操作,比方菜单按钮点击。重点在点击后并不间接实现,而是将申请封装为一个对象,能够了解为从间接实现:
function onClick() {// ... balabala 实现逻辑}
改为生成一个对象,序列化这个申请:
function onClick() {
concreteCommand.push({// ... 形容这个申请})
// 执行所有命令队列
concreteCommand.executeAll()}
看上去繁琐了一些,但失去了前面所说的益处:“从而使你可用不同的申请对客户进行参数化”, 也就是能够对任何申请进行参数化存储,咱们能够在任意时刻调用。 这相当于把握了执行机会,能够在任意时刻调用,以实现排队或记录日志,如果再记录下反向操作信息,就能够实现撤销重做了。
结构图
Command 是命令的接口,个别固定有一个 execute
办法。
ConcreteCommand 是命令接口的实现,它会注入具体执行者 Receiver
,它实现的 execute
办法会调用 receiver.execute
来具体执行。
Invoker
是执行申请的命令,其实下面都在推入命令,并没有真正执行,如果排队完结或点击撤销重做时,就触发了 Invoker 理论,就该调用对应的 Command 执行啦。
代码例子
上面例子应用 typescript 编写。
首先看最终执行态,最终执行须要先增加命令,再执行命令:
const command1 = new Command('balabala1')
const command2 = new Command('balabala2')
const invoker = new Invoker()
invoker.push(command1)
invoker.push(command2)
invoker.execute()
Invoker
外部用一个队列保护,执行的时候其实是 for
循环执行了每个 command.execute()
:
class Invoker {push(command) {
// 队列里推入命令
this.commands.push(command)
}
execute() {this.commands.forEach(command => command.execute())
// 别忘了清空 this.commands
}
}
弊病
命令模式须要留神序列化大小,个别分为:
- 仅记录操作。
- 记录全量快照。
- 全量快照共享内存。
记录操作是较为精密的治理形式,并且能够延长出协同编辑性能。记录快照要留神尽量共享内存,避免快照过大,而且协同编辑场景因为快照无奈做抵触解决,所以快照模式在协同编辑场景无奈利用。
另外要辨认没必要应用命令模式的场景,对于没有撤销重做的前端大部分场景来说,都无需改为命令模式。
总结
命令模式实质上就是将操作形象为可序列化的命令,使操作能够在适合的工夫执行,这种设计带来了许多额定益处。
利用命令模式能够达到高内聚低耦合的成果,晋升代码可维护性,也能够实现撤销重做、协同编辑等功能性需要。
探讨地址是:精读《设计模式 – Command(命令模式)》· Issue #295 · dt-fe/weekly
如果你想参加探讨,请 点击这里,每周都有新的主题,周末或周一公布。前端精读 – 帮你筛选靠谱的内容。
关注 前端精读微信公众号
版权申明:自在转载 - 非商用 - 非衍生 - 放弃署名(创意共享 3.0 许可证)