toBeTheLight.github.io 荒原

阅读:《图解设计模式》10 用类来表示


书中将 Command 命令模式、Interpreter 模式归纳为用类表现特殊东西的模式。 命令模式:将命令封装为一个类,分离命令调用者和命令实现者的责任,以便将命令进行储存、传递、调用、增加与管理。 解释器模式:将发生频率足够高的问题的各个实例表述为一个简单语言的句子,并构建一个解释器解释语言中的句子,其中的语法可以用类来解析。

Command 命令模式

定义

将命令封装为一个类,分离命令调用者和命令实现者的责任,以便将命令进行储存、传递、调用、增加与管理。

角色

  • 抽象命令类:声明执行命令的接口
  • 具体命令类:实现命令类的接口,并保有实现者,通过调用实现者实现操作。
  • 实现者:被命令类调用是具体命令的真正实现者。
  • 调用者:一般拥有很多命令对象,通过调用命令对象执行请求,而不直接调用实现者。

    JavaScript 实现

// 实现者
class Build {
  action () {
    console.log('开始构建')
  }
}
class Watch {
  action () {
    console.log('开始监听文件变化并自动构建')
  }
}
// 抽象命令类
class Command {
  execute () {
    throw new Error('需实现 Command 类的 execute 方法')
  }
}
// 具体命令类
class BuildCommand extends Command{
  constructor () {
    super()
    this.receiver = new Build()
  }
  execute {
    this.receiver.action()
  }
}
class WatchCommand extends Command{
  constructor () {
    super()
    this.receiver = new Watch()
  }
  execute {
    this.receiver.action()
  }
}
// 调用者
class Invoker {
  constructor () {
    this.cmd = null
  }
  setCommand (cmd) {
    this.cmd = cmd
  }
  call () {
    if (!this.cmd) return
    this.cmd.execute()
  }
}
// 使用
const invoker = new Invoker()
invoker.setCommand(new BuildCommand())
invoker.call()
invoker.setCommand(new WatchCommand())
invoker.call()

在谈到命令模式的定义的时候,我们还有一个目的,是实现对命令的存储和管理,在上面的代码中只体现除了对调用者和实现者的分离,那么管理如何显示呢,我们只需要对 Invoker 做少量修改。

const POOL = Symbol('cmdPool')
class Invoker {
  constructor () {
    this.cmd = null
    this[POOL] = []
  }
  setCommand (cmd) {
    this.cmd = cmd
  }
  call () {
    if (!this.cmd) return
    // 调用前存储命令对象
    this[POOL].push(cmd)
    this.cmd.execute()
  }
  replay () {
    // 以实现重播、删除等功能
    this[POOL].forEach(cmd => cmd.execute)
  }
}

Interpreter 解释器模式

定义

将发生频率足够高的问题的各个实例表述为一个简单语言的句子,并构建一个解释器解释语言中的句子。

角色

  • 抽象表达式:定义了语法树节点的共同接口,约定解释器的解释动作。
  • 终结符表达式:抽象表达式的子类,实现文法中与终结相关的操作。
  • 非终结符表达式:抽象表达式的子类,实现文法中与终结不相关的操作。
  • 环境:为解释器进行语法解析提供必要信息。
  • 客户端:调用解释器的解释方法

JavaScript实现

解释器模式用的实在是不多,做一个很好地实现实在是麻烦且浪费时间。

简要说明下,就是定义不同的语法,如,repeat、end 关键字,然后对同类关键字声明一个类,对语句的解析过程即对语句从前到后进行“阅读”,阅读的过程中将读到的关键字交给对应的类进行解析,此分发过程通常由一个通用的分发类进行。


Content