Node.js 设计模式笔记 —— Template 模式

Template 模式与 Strategy 模式有很多相似之处。Template 模式首先会定义一个虚拟基类,描述某个组件的骨架(即通用的部分),同时令骨架中存在的某些步骤处于未定义状态。
之后由虚拟基类的子类来实现上述组件中缺失的未定义部分,这部分之前未定义的方法称为 template methods
此模式的目的在于,定义一系列属于“同一家族”的类,能够囊括某个组件的所有变体。

UML of Template pattern

Template 和 Strategy 模式的目的是非常相似的,它们之间的区别主要在于结构和实现。
两者都允许我们在共享组件中通用部分的同时,修改组件中变化的部分,以此形成不同的变体。不同的地方在于,Strategy 是在运行时动态实现的,而 Template 则在子类定义的时刻就已经被确定了。

配置管理模板

mkdir template && cd template
npm install ini
npm install objec-path

package.json

{
  "type": "module"
}

configTemplate.js

import {promises as fsPromises} from 'fs'
import objectPath from 'object-path'

export class ConfigTemplate {
  async load(file) {
    console.log(`Deserializing from ${file}`)
    this.data = this._deserialize(
      await fsPromises.readFile(file, 'utf-8')
    )
  }

  async save(file) {
    console.log(`Serializing to ${file}`)
    await fsPromises.writeFile(file, this._serialize(this.data))
  }

  get(path) {
    return objectPath.get(this.data, path)
  }

  set(path, value) {
    return objectPath.set(this.data, path, value)
  }

  _serialize() {
    throw new Error('_serialize() must be implemented')
  }

  _deserialize() {
    throw new Error(`_deserialize() must be implemented`)
  }
}

其中 configTemplate 虚拟基类实现了配置管理逻辑中的通用部分,即加载和保存文件、获取和设置属性。同时不对序列化和反序列化部分的逻辑进行定义,从而可以通过再创建不同的 Config 子类(即后面的 jsonConfiginiConfig)来实现具体的序列化逻辑,进而支持特定的配置文件格式。

jsonConfig.js

import {ConfigTemplate} from './configTemplate.js'

export class JsonConfig extends ConfigTemplate {
  _deserialize(data) {
    return JSON.parse(data)
  }

  _serialize(data) {
    return JSON.stringify(data, null, ' ')
  }
}

iniConfig.js

import {ConfigTemplate} from './configTemplate.js'
import ini from 'ini'

export class IniConfig extends ConfigTemplate {
  _deserialize(data) {
    return ini.parse(data)
  }

  _serialize(data) {
    return ini.stringify(data)
  }
}

index.js

import {JsonConfig} from './jsonConfig.js'
import {IniConfig} from './iniConfig.js'

async function main() {
  const jsonConfig = new JsonConfig()
  await jsonConfig.load('samples/conf.json')
  jsonConfig.set('nodejs', 'design patterns')
  await jsonConfig.save('samples/conf_mod.json')

  const iniConifg = new IniConfig()
  await iniConifg.load('samples/conf.ini')
  iniConifg.set('nodejs', 'design patterns')
  await iniConifg.save('samples/conf_mod.ini')
}

main()

参考资料

Node.js Design Patterns: Design and implement production-grade Node.js applications using proven patterns and techniques, 3rd Edition

你可能感兴趣的:(Node.js 设计模式笔记 —— Template 模式)