Template 模式與 Strategy 模式有很多相似之處通铲。Template 模式首先會定義一個虛擬基類壮莹,描述某個組件的骨架(即通用的部分)删掀,同時令骨架中存在的某些步驟處于未定義狀態(tài)帆调。
之后由虛擬基類的子類來實現(xiàn)上述組件中缺失的未定義部分,這部分之前未定義的方法稱為 template methods迁匠。
此模式的目的在于,定義一系列屬于“同一家族”的類驹溃,能夠囊括某個組件的所有變體城丧。
Template 和 Strategy 模式的目的是非常相似的,它們之間的區(qū)別主要在于結(jié)構(gòu)和實現(xiàn)豌鹤。
兩者都允許我們在共享組件中通用部分的同時亡哄,修改組件中變化的部分,以此形成不同的變體布疙。不同的地方在于蚊惯,Strategy 是在運行時動態(tài)實現(xiàn)的,而 Template 則在子類定義的時刻就已經(jīng)被確定了灵临。
配置管理模板
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
虛擬基類實現(xiàn)了配置管理邏輯中的通用部分截型,即加載和保存文件、獲取和設(shè)置屬性儒溉。同時不對序列化和反序列化部分的邏輯進行定義宦焦,從而可以通過再創(chuàng)建不同的 Config 子類(即后面的 jsonConfig
和 iniConfig
)來實現(xiàn)具體的序列化邏輯,進而支持特定的配置文件格式顿涣。
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()