乐趣区

关于javascript:精读设计模式-Command-命令模式

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
  }
}

弊病

命令模式须要留神序列化大小,个别分为:

  1. 仅记录操作。
  2. 记录全量快照。
  3. 全量快照共享内存。

记录操作是较为精密的治理形式,并且能够延长出协同编辑性能。记录快照要留神尽量共享内存,避免快照过大,而且协同编辑场景因为快照无奈做抵触解决,所以快照模式在协同编辑场景无奈利用。

另外要辨认没必要应用命令模式的场景,对于没有撤销重做的前端大部分场景来说,都无需改为命令模式。

总结

命令模式实质上就是将操作形象为可序列化的命令,使操作能够在适合的工夫执行,这种设计带来了许多额定益处。

利用命令模式能够达到高内聚低耦合的成果,晋升代码可维护性,也能够实现撤销重做、协同编辑等功能性需要。

探讨地址是:精读《设计模式 – Command(命令模式)》· Issue #295 · dt-fe/weekly

如果你想参加探讨,请 点击这里,每周都有新的主题,周末或周一公布。前端精读 – 帮你筛选靠谱的内容。

关注 前端精读微信公众号

版权申明:自在转载 - 非商用 - 非衍生 - 放弃署名(创意共享 3.0 许可证)

退出移动版