【JavaScript设计模式】行为型设计模式--模板方法模式
2017-05-22 16:17
295 查看
模板方法模式是一种只需要使用继承就可以实现的非常简单的模式。模板方法模式是由两部分组成,第一部分是抽象类,第二部分是具体的实现子类。通常在抽象父类中封装了子类的算法框架,其中主要是包括一些公共的方法以及封装所有子类中所有方法的执行顺序。那子类通过继承这个抽象类,也就是继承了整个算法结构,并且可以选择重写父类的方法。
在模板方法模式中,还引入了另外一个设计原则--“好莱坞原则”。为了说明这个原则,在这里引入一个段子:
| 好莱坞无疑是演员的天堂,但好莱坞也有很多找不到工作的新人演员,许多新人演员在好莱坞把简历递给演艺公司之后就只有回家等待电话,有时候演员等得不耐烦了,给演艺公司打电话询问情况,演艺公司往往这样回答:“不要来找我,我会给你打电话。”。这样的规则就称作是好莱坞规则。
模板方法模式是好莱坞原则的一个典型应用场景,它与好莱坞原则的联系非常明显。当我们使用模板方法编写一个程序时,就意味着子类放弃了对自己的控制权,而是改为父类通知子类,哪些方法应该在什么时候被调用。作为子类,只负责提供一些设计上的细节。
下面通过一个具体的例子Coffee和Tea进行说明模板方法模式的使用。
咖啡和茶是一个非常经典的例子,经常用来讲解模板方法模式。
1、泡一杯咖啡
泡咖啡的步骤通常如下:
把水煮沸;
用沸水冲泡咖啡;
把咖啡倒进杯子;
加糖和牛奶。
我们通过代码实现一下这个过程:
2、泡一壶茶
泡一壶茶的步骤通常如下:
把水煮沸;
用沸水浸泡茶叶;
把茶水倒进杯子;
加柠檬。
我们通过代码实现一下这个过程:
通过对比冲咖啡和泡茶,可以总结为以下步骤:
把水煮沸;
用沸水冲泡饮料;
把饮料倒进杯子;
加调料。
现在进行抽象一个类来表示泡一杯饮料的整个过程,实现代码如下:
接下来我们要创建咖啡和茶的具体实现。
咖啡:
var Coffee = function(){};
Coffee.prototype = new Beverage();
Coffee.prototype.brew = function(){
console.log('2.用沸水冲泡咖啡');
};
Coffee.prototype.pourIncup = function(){
console.log('3.把咖啡倒进杯子');
}
Coffee.prototype.addCondiments = function(){
console.log('4.加糖和牛奶');
}
var coffee = new Coffee();
coffee.init();
茶:
var Tea = function(){};
Tea.prototype = new Beverage();
Tea.prototype.brew = function(){
console.log('2.用沸水冲泡咖啡');
};
Tea.prototype.pourIncup = function(){
console.log('3.把咖啡倒进杯子');
}
Tea.prototype.addCondiments = function(){
console.log('4.加糖和牛奶');
}
var tea = new Tea();
tea.init();5、总结
模板方法应用于下列情况:
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复,不同之处分离为新的操作,分别实现
控制子类扩展,模板方法可以只在特定点调用“Hook”操作,这样就只允许在这些点进行扩展。
在模板方法模式中,还引入了另外一个设计原则--“好莱坞原则”。为了说明这个原则,在这里引入一个段子:
| 好莱坞无疑是演员的天堂,但好莱坞也有很多找不到工作的新人演员,许多新人演员在好莱坞把简历递给演艺公司之后就只有回家等待电话,有时候演员等得不耐烦了,给演艺公司打电话询问情况,演艺公司往往这样回答:“不要来找我,我会给你打电话。”。这样的规则就称作是好莱坞规则。
模板方法模式是好莱坞原则的一个典型应用场景,它与好莱坞原则的联系非常明显。当我们使用模板方法编写一个程序时,就意味着子类放弃了对自己的控制权,而是改为父类通知子类,哪些方法应该在什么时候被调用。作为子类,只负责提供一些设计上的细节。
下面通过一个具体的例子Coffee和Tea进行说明模板方法模式的使用。
咖啡和茶是一个非常经典的例子,经常用来讲解模板方法模式。
1、泡一杯咖啡
泡咖啡的步骤通常如下:
把水煮沸;
用沸水冲泡咖啡;
把咖啡倒进杯子;
加糖和牛奶。
我们通过代码实现一下这个过程:
var Coffee = function(){}; Coffee.prototype.boilWater = function(){ console.log('1.把水煮沸'); } Coffee.prototype.brewCoffeeGriends = function(){ console.log('2.用沸水冲泡咖啡'); } Coffee.prototype.pourIncup = function(){ console.log('3.把咖啡倒进杯子'); } Coffee.prototype.addSugarAndMilk = function(){ console.log('4.加糖和牛奶'); } Coffee.prototype.init = function(){ this.boilWater(); this.brewCoffeeGriends(); this.pourIncup(); this.addSugarAndMilk(); } var coffee = new Coffee(); coffee.init();
2、泡一壶茶
泡一壶茶的步骤通常如下:
把水煮沸;
用沸水浸泡茶叶;
把茶水倒进杯子;
加柠檬。
我们通过代码实现一下这个过程:
//泡茶 var Tea = function(){}; Tea.prototype.boilWater = function(){ console.log('1.把水煮沸'); } Tea.prototype.brewCoffeeGriends = function(){ console.log('2.用沸水浸泡茶叶'); } Tea.prototype.pourIncup = function(){ console.log('3.把茶水倒进杯子'); } Tea.prototype.addSugarAndMilk = function(){ console.log('4.加柠檬'); } Tea.prototype.init = function(){ this.boilWater(); this.brewCoffeeGriends(); this.pourIncup(); this.addSugarAndMilk(); } var tea = new Tea(); tea.init();3、分离出共同点
通过对比冲咖啡和泡茶,可以总结为以下步骤:
把水煮沸;
用沸水冲泡饮料;
把饮料倒进杯子;
加调料。
现在进行抽象一个类来表示泡一杯饮料的整个过程,实现代码如下:
var Beverage = function(){}; Beverage.prototype.boilWater = function(){ console.log("1.把水煮沸"); }; Beverage.prototype.brew = function(){};//空方法,应该由子类重写 Beverage.prototype.pourIncup = function(){};//空方法,应该由子类重写 Beverage.prototype.addCondiments = function(){};//空方法,应该由子类重写 Beverage.prototype.init = function(){ this.boilWater(); this.brew(); this.pourIncup(); this.addCondiments(); }4、实现Coffee和Tea子类
接下来我们要创建咖啡和茶的具体实现。
咖啡:
var Coffee = function(){};
Coffee.prototype = new Beverage();
Coffee.prototype.brew = function(){
console.log('2.用沸水冲泡咖啡');
};
Coffee.prototype.pourIncup = function(){
console.log('3.把咖啡倒进杯子');
}
Coffee.prototype.addCondiments = function(){
console.log('4.加糖和牛奶');
}
var coffee = new Coffee();
coffee.init();
茶:
var Tea = function(){};
Tea.prototype = new Beverage();
Tea.prototype.brew = function(){
console.log('2.用沸水冲泡咖啡');
};
Tea.prototype.pourIncup = function(){
console.log('3.把咖啡倒进杯子');
}
Tea.prototype.addCondiments = function(){
console.log('4.加糖和牛奶');
}
var tea = new Tea();
tea.init();5、总结
模板方法应用于下列情况:
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复,不同之处分离为新的操作,分别实现
控制子类扩展,模板方法可以只在特定点调用“Hook”操作,这样就只允许在这些点进行扩展。
相关文章推荐
- 设计模式笔记(14)---模板方法模式(行为型)
- 面向对象设计模式之TemplateMethod模板方法(行为型)
- 设计模式23——行为型模式之模板方法模型
- 设计模式--模板方法模式Template method(类行为型)
- 设计模式16:模板方法模式【行为型】
- 设计模式学习之模板方法模式(TemplateMethod,行为型模式)(9)
- 设计模式-行为型之模板方法模式
- JAVA设计模式(17):行为型-模板方法模式(Template Method)
- 设计模式 ( 十九 ) 模板方法模式Template method(类行为型)
- 设计模式笔记(14)---模板方法模式(行为型)
- 设计模式笔记(14)---模板方法模式(行为型)
- 设计模式学习日志(14)-TemplateMethod模板方法(行为型模式)
- 设计模式13:Template Method 模板方法模式(行为型模式)
- 设计模式 ( 十九 ) 模板方法模式Template method(类行为型)
- 设计模式17---设计模式之模板方法模式(Template Method)(行为型)
- [设计模式笔记]三. 行为型模式--24. Template Method模式(模板方法)类行为型模式(一)
- GoF23种设计模式之行为型模式之模板方法
- 设计模式笔记 13. TemplateMethod 模板方法模式(行为型模式)
- 设计模式 - 行为型模式 - 模板方法模式
- Java设计模式之模板方法模式或者说模板设计模式(属于行为型)