【JavaScript设计模式】行为型设计模式--模板方法模式

      模板方法模式是一种只需要使用继承就可以实现的非常简单的模式。模板方法模式是由两部分组成,第一部分是抽象类,第二部分是具体的实现子类。通常在抽象父类中封装了子类的算法框架,其中主要是包括一些公共的方法以及封装所有子类中所有方法的执行顺序。那子类通过继承这个抽象类,也就是继承了整个算法结构,并且可以选择重写父类的方法。

      在模板方法模式中,还引入了另外一个设计原则--“好莱坞原则”。为了说明这个原则,在这里引入一个段子:

      | 好莱坞无疑是演员的天堂,但好莱坞也有很多找不到工作的新人演员,许多新人演员在好莱坞把简历递给演艺公司之后就只有回家等待电话,有时候演员等得不耐烦了,给演艺公司打电话询问情况,演艺公司往往这样回答:“不要来找我,我会给你打电话。”。这样的规则就称作是好莱坞规则。

     模板方法模式是好莱坞原则的一个典型应用场景,它与好莱坞原则的联系非常明显。当我们使用模板方法编写一个程序时,就意味着子类放弃了对自己的控制权,而是改为父类通知子类,哪些方法应该在什么时候被调用。作为子类,只负责提供一些设计上的细节。

     下面通过一个具体的例子Coffee和Tea进行说明模板方法模式的使用。

     咖啡和茶是一个非常经典的例子,经常用来讲解模板方法模式。

1、泡一杯咖啡

     泡咖啡的步骤通常如下:

  1. 把水煮沸;
  2. 用沸水冲泡咖啡;
  3. 把咖啡倒进杯子;
  4. 加糖和牛奶。
     我们通过代码实现一下这个过程:
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、泡一壶茶

     泡一壶茶的步骤通常如下:

  1. 把水煮沸;
  2. 用沸水浸泡茶叶;
  3. 把茶水倒进杯子;
  4. 加柠檬。
   我们通过代码实现一下这个过程:

//泡茶
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、分离出共同点

      通过对比冲咖啡和泡茶,可以总结为以下步骤:

  1. 把水煮沸;
  2. 用沸水冲泡饮料;
  3. 把饮料倒进杯子;
  4. 加调料。
      现在进行抽象一个类来表示泡一杯饮料的整个过程,实现代码如下:
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、总结

模板方法应用于下列情况:

  1. 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现
  2. 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复,不同之处分离为新的操作,分别实现
  3. 控制子类扩展,模板方法可以只在特定点调用“Hook”操作,这样就只允许在这些点进行扩展。




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值