一、Temlplate Child 交给子类设计模式定义
父类中定义流程的框架,在子类中具体实现。每个子类针对没件事情的做法可能不同,但是做的事情都一样。
二、需求
有时候业务需要自动识别满足一定规则下的所有的子类,并且根据指定标识分发业务数据到子类处理。
三、环境相关
语言: javascript
四、实现场景
- 设计模式
父类定义抽象方法,子类去实现。 - 代码逻辑
-
定义每个实例的instanceId
-
父类TaskHandler中定义子类任务都需要做dealTask(哪些事情)
-
父类TaskHandler把任务的做法dealTask交给了子类
-
定义父类静态方法registInstance
function TaskHandler (instanceId) {
this.instanceId = instanceId
this.registInstance = function () {
// 子类调this是子类实例
TaskHandler.registInstance.call(this)
}
// 每实例化调用一次就注册一次实例
this.registInstance.call(this)
// 空函数目的就是让子类自己决定
this.dealTask = function () {}
}
// 定义父类静态方法 【注册】】 这个方法子类可以通过调用父类的this.registTask 间接调用
TaskHandler.registInstance = function () {
console.log("registTask", this)
if (!TaskHandler.cacheInstance) {
TaskHandler.cacheInstance = []
}
TaskHandler.cacheInstance.push(this);
}
// 定义父类静态方法 【发布】 这个方法只能由父类发动
TaskHandler.triggerTasks = function (tasklist) {
// tasklist可以是一个任务数组[task] or 也可以是一个任务task
if (tasklist instanceof Array) {
// 该做一堆事儿了哈
tasklist.forEach(task => {
TaskHandler.cacheInstance.forEach(instance => {
instance.dealTask.call(instance, task)
})
})
} else if (typeof tasklist === 'sting' && [...tasklist].length > 0) {
// 做一件事儿哈
TaskHandler.cacheInstance.forEach(instance => {
instance.dealTask.call(instance, tasklist)
})
}
}
复制代码
- 子类中调用registInstance,调用父类静态方法registInstance,自动注册实例到父类中,方便父类管理
function EasyTask (instanceId) {
this.instanceId = instanceId
this.difficultType = 1 // 简单
TaskHandler.call(this, this.instanceId)
this.dealTask = function (taskName) {
console.log(this.instanceId + '我是简单任务的做法,要开始干活儿啦', '任务名字是' + taskName)
// ...
}
}
function DifficultTask (instanceId) {
this.instanceId = instanceId
this.difficultType = 2 /// 困难
TaskHandler.call(this, this.instanceId)
this.dealTask = function (taskName) {
console.log(this.instanceId + '我是困难任务的做法,要开始干活儿啦', '任务名字是' + taskName)
// ...
}
}
复制代码
- 子类都注册好了实例之后,通过父类registInstance时间分发给子类处理各自的事情
const easy = new EasyTask("小憨憨")
const diffocult = new DifficultTask("大憨憨")
TaskHandler.triggerTasks(['上树', '下树'])
// 打印结果
registTask EasyTask {
instanceId: '小憨憨',
difficultType: 1,
registInstance: [Function]
}
registTask DifficultTask {
instanceId: '大憨憨',
difficultType: 2,
registInstance: [Function]
}
小憨憨我是简单任务的做法,要开始干活儿啦 任务名字是上树
大憨憨我是困难任务的做法,要开始干活儿啦 任务名字是上树
小憨憨我是简单任务的做法,要开始干活儿啦 任务名字是下树
大憨憨我是困难任务的做法,要开始干活儿啦 任务名字是下树
//
复制代码
五、小结
- 无论在父类中使用哪一个子类的实例,都可以正常工作,这种思想是一个通用的继承原则,不仅限于Template Method
- 我们想让哪个子类干活就注册哪个子类,然后让父类去派发他们。重新定义子类里边的方法,就可以改变程序的行为
- Template Method中,方法调用逻辑定义在父类,子类就更加轻松,但是子类也就不灵活。如果父类定义的方法过少,子类就会臃肿,甚至子类间会有重复代码。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END