模板方法模式是一種只需使用繼承就能夠實現的很是簡單的模式。模板方法模式由兩部分結構組成,第一部分是抽象父類,第二部分是具體的實現子類。一般 在抽象父類中封裝了子類的算法框架,包括實現一些公共方法以及封裝子類中全部方法的執行順序。子類經過繼承這個抽象類,也繼承了整個算法結構,而且能夠選擇重寫父類的方法。相同的方法都被提取到父類, 相似於Java中的繼承的模式,父類定義方法, 子類重寫方法算法
首先分析比較一下泡咖啡和泡茶的流程: 設計模式
總結爲四個步驟bash
// 飲料
function Beverage() {}
Beverage.prototype.boilWater = () => {
console.log(' => 把水煮沸');
}
Beverage.prototype.brew = () => { throw new Error('子類必須重寫此方法'); }
Beverage.prototype.pourInCup = () => { throw new Error('子類必須重寫此方法'); }
Beverage.prototype.addCondiments = () => { throw new Error('子類必須重寫此方法'); }
Beverage.prototype.init = function() {
this.boilWater();
this.brew();
this.pourInCup();
this.addCondiments();
}
function Coffee() {}
Coffee.prototype = new Beverage();
Coffee.prototype.brew = () => { console.log(' => 泡咖啡',);}
Coffee.prototype.pourInCup = () => { console.log(' => 向杯子倒咖啡',);}
Coffee.prototype.addCondiments = () => { console.log(' => 加糖和牛奶',);}
複製代碼
function Beverage(params) {
const boilWater = () => { console.log(' => 把水煮沸',); }
const brew = params.brew && (() => { throw new Error('子類必須重寫此方法'); });
const pourInCup = params.pourInCup && (() => { throw new Error('子類必須重寫此方法'); });
const addCondiments = params.addCondiments && (() => { throw new Error('子類必須重寫此方法'); });
const F;
F.prototype.init = () => {
boilWater();
brew();
pourInCup();
addCondiments();
}
return F;
}
const Coffee = Beverage({
brew: () => { console.log(' => 泡咖啡',);},
pourInCup: () => { console.log(' => 向杯子倒咖啡',);},
addCondiments: () => { console.log(' => 加糖和牛奶',);}
});
const Tea = Beverage({
brew: () => { console.log(' => 泡茶',);},
pourInCup: () => { console.log(' => 向杯子倒茶',);},
addCondiments: () => { console.log(' => 檸檬',);}
});
const coffee = new Coffee();
coffee.init();
const tea = new Tea();
tea.init();
複製代碼
模板方法模式是一種典型的經過封裝變化提升系統擴展性的設計模式。在傳統的面嚮對象語言中,一個運用了模板方法模式的程序中,子類的方法種類和執行順序都是不變的,因此咱們把這部分邏輯抽象到父類的模板方法裏面。而子類的方法具體怎麼實現則是可變的,因而咱們把這 部分變化的邏輯封裝到子類中。經過增長新的子類,咱們便能給系統增長新的功能,並不須要改 動抽象父類以及其餘子類,這也是符合開放封閉原則的。框架