定义: 在继承的基础上, 在父类中定义好执行的算法。
来对比下泡茶和泡咖啡过程中的异同
步骤 | 泡茶 | 泡咖啡 |
---|---|---|
1 | 烧开水 | 烧开水 |
2 | 浸泡茶叶 | 冲泡咖啡 |
3 | 倒入杯子 | 倒入杯子 |
4 | 加柠檬 | 加糖 |
可以清晰地看出仅仅在步骤 2 和 4 上有细微的差别, 下面着手实现:
const Drinks = function() {}Drinks.prototype.firstStep = function() {console.log('烧开水')}Drinks.prototype.secondStep = function() {}Drinks.prototype.thirdStep = function() {console.log('倒入杯子')}Drinks.prototype.fourthStep = function() {}Drinks.prototype.init = function() { // 模板方法模式核心: 在父类上定义好执行算法this.firstStep()this.secondStep()this.thirdStep()this.fourthStep()}const Tea = function() {}Tea.prototype = new DrinksTea.prototype.secondStep = function() {console.log('浸泡茶叶')}Tea.prototype.fourthStep = function() {console.log('加柠檬')}const Coffee = function() {}Coffee.prototype = new DrinksCoffee.prototype.secondStep = function() {console.log('冲泡咖啡')}Coffee.prototype.fourthStep = function() {console.log('加糖')}const tea = new Tea()tea.init()// 烧开水// 浸泡茶叶// 倒入杯子// 加柠檬const coffee = new Coffee()coffee.init()// 烧开水// 冲泡咖啡// 倒入杯子// 加糖
假如客人不想加佐料(糖、柠檬)怎么办, 这时可以引人钩子来实现之, 实现逻辑如下:
// ...Drinks.prototype.ifNeedFlavour = function() { // 加上钩子return true}Drinks.prototype.init = function() { // 模板方法模式核心: 在父类上定义好执行算法this.firstStep()this.secondStep()this.thirdStep()if (this.ifNeedFlavour()) { // 默认是 true, 也就是要加调料this.fourthStep()}}// ...const Coffee = function() {}Coffee.prototype = new Drinks()// ...Coffee.prototype.ifNeedFlavour = function() {return window.confirm('是否需要佐料吗?') // 弹框选择是否佐料}