深入理解JavaScript系列(41):设计模式之模板方法详解


Posted in Javascript onMarch 04, 2015

介绍

模板方法(TemplateMethod)定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

模板方法是一种代码复用的基本技术,在类库中尤为重要,因为他们提取了类库中的公共行为。模板方法导致一种反向的控制结构,这种结构就是传说中的“好莱坞法则”,即“别找找我们,我们找你”,这指的是父类调用一个类的操作,而不是相反。具体体现是面向对象编程编程语言里的抽象类(以及其中的抽象方法),以及继承该抽象类(和抽象方法)的子类。

正文

举个例子,泡茶和泡咖啡有同样的步骤,比如烧开水(boilWater)、冲泡(brew)、倒在杯子里(pourOnCup),加小料(addCondiments)等等。但每种饮料冲泡的方法以及所加的小料不一样,所以我们可以利用模板方法实现这个主要步骤。

首先先来定义抽象步骤:

var CaffeineBeverage = function () {
};

CaffeineBeverage.prototype.prepareRecipe = function () {

    this.boilWater();

    this.brew();

    this.pourOnCup();

    if (this.customerWantsCondiments()) {

        // 如果可以想加小料,就加上

 this.addCondiments();

    }

};

CaffeineBeverage.prototype.boilWater = function () {

    console.log("将水烧开!");

};

CaffeineBeverage.prototype.pourOnCup = function () {

    console.log("将饮料到再杯子里!");

};

CaffeineBeverage.prototype.brew = function () {

    throw new Error("该方法必须重写!");

};

CaffeineBeverage.prototype.addCondiments = function () {

    throw new Error("该方法必须重写!");

};

// 默认加上小料

CaffeineBeverage.prototype.customerWantsCondiments = function () {

    return true;

};

该函数在原型上扩展了所有的基础步骤,以及主要步骤,冲泡和加小料步骤没有实现,供具体饮料所对应的函数来实现,另外是否加小料(customerWantsCondiments )默认返回true,子函数重写的时候可以重写该值。

下面两个函数分别是冲咖啡和冲茶所对应的函数:

// 冲咖啡

var Coffee = function () {

    CaffeineBeverage.apply(this);

};

Coffee.prototype = new CaffeineBeverage();

Coffee.prototype.brew = function () {

    console.log("从咖啡机想咖啡倒进去!");

};

Coffee.prototype.addCondiments = function () {

    console.log("添加糖和牛奶");

};

Coffee.prototype.customerWantsCondiments = function () {

    return confirm("你想添加糖和牛奶吗?");

};
//冲茶叶

var Tea = function () {

    CaffeineBeverage.apply(this);

};

Tea.prototype = new CaffeineBeverage();

Tea.prototype.brew = function () {

    console.log("泡茶叶!");

};

Tea.prototype.addCondiments = function () {

    console.log("添加柠檬!");

};

Tea.prototype.customerWantsCondiments = function () {

    return confirm("你想添加柠檬嘛?");

};

另外使用confirm,可以让用户自己选择加不加小料,很不错,不是嘛?

总结

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

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

和策略模式不同,模板方法使用继承来改变算法的一部分,而策略模式使用委托来改变整个算法。

Javascript 相关文章推荐
JavaScript 获取事件对象的注意点
Jul 29 Javascript
JavaScript在IE和Firefox浏览器下的7个差异兼容写法小结
Jun 18 Javascript
jQuery实现折线图的方法
Feb 28 Javascript
jQuery实现仿淘宝带有指示条的图片转动切换效果完整实例
Mar 04 Javascript
JavaScript实现为指定对象添加多个事件处理程序的方法
Apr 17 Javascript
javascript函数命名的三种方式及区别介绍
Mar 22 Javascript
jquery获取复选框的值的简单实例
May 26 Javascript
JavaScript ES5标准中新增的Array方法
Jun 28 Javascript
AngulaJS路由 ui-router 传参实例
Apr 28 Javascript
vue.js实现标签页切换效果
Jun 07 Javascript
js中对象与对象创建方法的各种方法
Feb 27 Javascript
构建Vue大型应用的10个最佳实践(小结)
Nov 07 Javascript
深入理解JavaScript系列(40):设计模式之组合模式详解
Mar 04 #Javascript
百度地图自定义控件分享
Mar 04 #Javascript
jQuery实现仿淘宝带有指示条的图片转动切换效果完整实例
Mar 04 #Javascript
深入理解JavaScript系列(39):设计模式之适配器模式详解
Mar 04 #Javascript
深入理解JavaScript系列(38):设计模式之职责链模式详解
Mar 04 #Javascript
教你如何使用firebug调试功能了解javascript闭包和this
Mar 04 #Javascript
深入理解JavaScript系列(37):设计模式之享元模式详解
Mar 04 #Javascript
You might like
PHP类的自动加载机制实现方法分析
2019/01/10 PHP
静态图片的十一种滤镜效果--不支持Ie7及非IE浏览器。
2007/03/06 Javascript
JQuery textlimit 显示用户输入的字符数 限制用户输入的字符数
2009/05/14 Javascript
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
2009/08/28 Javascript
javascript 模拟点击广告
2010/01/02 Javascript
使用dynatrace-ajax跟踪JavaScript的性能
2010/04/12 Javascript
SharePoint 客户端对象模型 (一) ECMA Script
2011/05/22 Javascript
jquery 实现上下滚动效果示例代码
2013/08/09 Javascript
js获取php变量的实现代码
2013/08/10 Javascript
查看大图功能代码jquery版
2013/11/05 Javascript
Bootstrap自定义文件上传下载样式
2016/05/26 Javascript
JavaScript新增样式规则(推荐)
2016/07/19 Javascript
BootStrap table表格插件自适应固定表头(超好用)
2016/08/24 Javascript
Bootstrap Modal遮罩弹出层代码分享
2016/11/21 Javascript
AngularJS 使用ng-repeat报错 [ngRepeat:dupes]
2017/01/19 Javascript
Java与JavaScript中判断两字符串是否相等的区别
2017/03/13 Javascript
详解nodejs的express如何自动生成项目框架
2017/07/12 NodeJs
JS文件中加载jquery.js的实例代码
2018/05/05 jQuery
vue路由组件按需加载的几种方法小结
2018/07/12 Javascript
JavaScript实现简单音乐播放器
2020/04/17 Javascript
jquery实现选项卡切换代码实例
2019/05/14 jQuery
[01:01:41]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma BO3 第二场 1月31日
2021/03/11 DOTA
python将MongoDB里的ObjectId转换为时间戳的方法
2015/03/13 Python
python中日期和时间格式化输出的方法小结
2015/03/19 Python
Flask框架WTForm表单用法示例
2018/07/20 Python
python实现词法分析器
2019/01/31 Python
简单了解Django ContentType内置组件
2019/07/23 Python
将python依赖包打包成window下可执行文件bat方式
2019/12/26 Python
pandas参数设置的实用小技巧
2020/08/23 Python
美国男士和女士奢侈品折扣手表购物网站:Certified Watch Store
2018/06/13 全球购物
高中毕业自我鉴定范文
2013/10/02 职场文书
保险经纪人求职信
2014/03/11 职场文书
讲座主持词
2014/03/20 职场文书
课程设计的心得体会
2014/09/03 职场文书
个人纪律作风整改措施思想汇报
2014/10/12 职场文书
2016年清明节寄语
2015/12/04 职场文书