模板方法模式是一种典型的通过封装变化提高系统扩展性的设计模式。
模板方法模式 :在一个方法中定义一个算法的骨架,而将一些步骤的实现延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中某些步骤的具体实现。
一个运用了模板方法模式的程序中,子类的方法种类和执行顺序都是不变的
- 逻辑抽象到父类模板方法里面
- 子类方法是可变的(部分变化封装在子类中)
我们便能给系统增加新的功能,并不需要改动抽象父类以及其他子类,这也是符合开放封闭原则的。
第一步 : 父类模板方法
var Beverage = function( param ){
var boilWater = function(){
console.log( '把水煮沸' );
};
var brew = param.brew || function(){
throw new Error( '必须传递 brew 方法' );
};
var pourInCup = param.pourInCup || function(){
throw new Error( '必须传递 pourInCup 方法' );
};
var addCondiments = param.addCondiments || function(){
throw new Error( '必须传递 addCondiments 方法' );
};
var F = function(){};
F.prototype.init = function(){
boilWater();
brew();
pourInCup();
addCondiments();
};
return F;
};
第二步 :子类的方法
var Coffee = Beverage({
brew: function(){
console.log( '用沸水冲泡咖啡' );
},
pourInCup: function(){
console.log( '把咖啡倒进杯子' );
},
addCondiments: function(){
console.log( '加糖和牛奶' );
}
});
var coffee = new Coffee();
coffee.init();
var Tea = Beverage({
brew: function(){
console.log( '用沸水浸泡茶叶' );
},
pourInCup: function(){
console.log( '把茶倒进杯子' );
},
addCondiments: function(){
console.log( '加柠檬' );
}
});
var tea = new Tea();
tea.init();
总结 :在这段代码中,我们把 brew、pourInCup、addCondiments 这些方法依次传入 Beverage 函数,
Beverage 函数被调用之后返回构造器 F。F 类中包含了“模板方法”F.prototype.init。跟继承得
到的效果一样,该“模板方法”里依然封装了饮料子类的算法框架。