模板方法模式 假如我們有一些對象,各個對象之間有一些相同的行為,也有一些不同的行為,這時,我們就可以用模板方法模式來把相同的部分上移到它們的共同原型中(父類),而將不同的部分留給自己各自重新實現。 模板方法:在這些平行對象的共同原型中定義的一個方法,它封裝了子類的演算法框架,它作為一個演算法的模板,指導 ...
模板方法模式
假如我們有一些對象,各個對象之間有一些相同的行為,也有一些不同的行為,這時,我們就可以用模板方法模式來把相同的部分上移到它們的共同原型中(父類),而將不同的部分留給自己各自重新實現。
模板方法:在這些平行對象的共同原型中定義的一個方法,它封裝了子類的演算法框架,它作為一個演算法的模板,指導子類以何種順序去執行哪些方法。
模板方法常常被架構師用於搭建項目的框架,架構師定好了框架的骨架,程式員們繼承框架的結構後,負責往裡面填空。
模板方法模式中,常常用到一個鉤子方法:在父類中的容易變化的方法上放置鉤子,模板方法依據鉤子方法的返回值來決定是否執行容易變化的方法。
模板方法模式是一種基於繼承的設計模式,但在JavaScript中也可以通過高階函數來實現。
基於繼承的模板方法模式:
//模板方法模式
//泡茶和沖咖啡,有相似的方法,也有不同的方法
//相似的方法在父類中實現,不同的方法在子類中各自重寫
var Beverage = function () {};
Beverage.prototype.boilWater = function () {
console.log('把水煮沸');
};
Beverage.prototype.pourMaterial = function (material) {
console.log('把'+material+'倒進杯子');
};
Beverage.prototype.pourInCup = function () {
console.log('把沸水倒進杯子');
};
Beverage.prototype.addCondiments = function () {
throw new Error('子類必須自行實現該方法');
};
//鉤子方法,是否需要加配料
Beverage.prototype.isWantCondiments = function () {
return true; //預設為true,子類自行實現來改變返回值
};
//模板方法,規定了各個方法的執行順序
Beverage.prototype.init = function (material) {
this.boilWater();
this.pourMaterial(material);
this.pourInCup();
if(this.isWantCondiments()){ //根據鉤子方法的返回值決定是否執行
this.addCondiments();
}
};
//====子類
var Coffee = function () {};
Coffee.prototype = new Beverage(coffee);
Coffee.prototype.addCondiments = function () {
console.log('加糖');
};
Coffee.prototype.isWantCondiments = function () {
return window.confirm('請問需要加糖嗎?');
};
//調用
var coffee = '咖啡粉';
var coffee1 = new Coffee();
coffee1.init(coffee);
通過高階函數來實現:
var Beverage1 = function (obj,material) {
var boilWater = function(){
console.log('把水煮沸');
};
var pourMaterial = function(material){
console.log('把'+material+'倒進杯子');
};
var pourInCup = function () {
console.log('把沸水倒進杯子');
};
var addCondiments = obj.addCondiments||function () {
throw new Error('子類必須自行實現該方法');
};
var isWantCondiments = obj.isWantCondiments||function () {
return true; //預設為true,子類自行實現來改變返回值
};
var F = function(){};
F.prototype.init = function(){
boilWater();
pourMaterial(material);
pourInCup();
if(isWantCondiments()){ //根據鉤子方法的返回值決定是否執行
addCondiments();
}
};
return F;
};
//定義子類
var Coffee1 = Beverage1({
addCondiments: function(){
console.log('加糖');
},
isWantCondiments: function () {
return window.confirm('請問需要加糖嗎?');
}
},'咖啡粉');
var Tea1 = Beverage1({
addCondiments: function(){
console.log('加檸檬');
},
isWantCondiments: function () {
return window.confirm('請問需要加檸檬嗎?');
}
},'茶葉');
var aCupOfCoffee = new Coffee1();
aCupOfCoffee.init();
//把水煮沸
//把咖啡粉倒進杯子
//把沸水倒進杯子
//加糖(點確定)
var aCupOfTea = new Tea1();
aCupOfTea.init();
//把水煮沸
//把茶葉倒進杯子
//把沸水倒進杯子
//加檸檬(點確定)
參考文獻: 《JavaScript模式》 《JavaScript設計模式與開發實踐》