意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
使用场景: 1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。
举个例子:
在游戏里,每种武器的使用流程基本都一样的,只是细节的差异,那我们把共同的流程抽象起来,放到抽象父类中,子类继承父类,实现细节的部分,公共部分直接沿用父类的,并且不允许覆盖父类的这个流程方法。
代码:
// 抽象父类
abstract class AbstractWeapon {
// 抽象的获取子弹数量细节
protected abstract left: () => number
// 抽象的装弹细节
protected abstract load: () => void
// 抽象的瞄准细节
protected abstract focus: () => void
// 抽象的射击细节
protected abstract shot: () => void
// 具体的使用流程
public fire() {
// 判断子弹数量
if (this.left() === 0) {
// 装弹
this.load()
}
// 瞄准
this.focus()
// 射击
this.shot()
}
}
// 自动步枪
class RifleGun extends AbstractWeapon {
public left = () => {
console.log('RifleGun剩余子弹:10发')
return 10
}
public load = () => {
console.log('RifleGun装弹:+10发')
}
public focus = () => {
console.log('RifleGun瞄准')
}
public shot = () => {
console.log('RifleGun开枪开枪!砰砰砰!')
}
}
// 机枪阵
class MG42 extends AbstractWeapon {
public left = () => {
console.log('MG42没有子弹了')
return 0
}
public load = () => {
console.log('MG42装弹:+1000发')
}
public focus = () => {
console.log('MG42瞄准')
}
public shot = () => {
console.log('MG42开枪开枪!哒哒哒!')
}
}
// Test
const rif = new RifleGun()
rif.fire()
const mg42 = new MG42()
mg42.fire()
输出结果:
[LOG]: RifleGun剩余子弹:10发
[LOG]: RifleGun瞄准
[LOG]: RifleGun开枪开枪!砰砰砰!
[LOG]: MG42没有子弹了
[LOG]: MG42装弹:+1000发
[LOG]: MG42瞄准
[LOG]: MG42开枪开枪!哒哒哒!