深入理解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 相关文章推荐
jquery 读取页面load get post ajax 四种方式代码写法
Apr 02 Javascript
很棒的学习jQuery的12个网站推荐
Apr 28 Javascript
JavaScript面向对象之Prototypes和继承
Jul 12 Javascript
深入解析contentWindow, contentDocument
Jul 04 Javascript
深入浅析javascript中的作用域(推荐)
Jul 19 Javascript
AngularJS教程之MVC体系结构详解
Aug 16 Javascript
简单的vue-resourse获取json并应用到模板示例
Feb 10 Javascript
jQuery中的on与bind绑定事件区别实例详解
Feb 28 Javascript
Node.js数据库操作之查询MySQL数据库(二)
Mar 04 Javascript
自适应布局meta标签中viewport、content、width、initial-scale、minimum-scale、maximum-scale总结
Aug 18 Javascript
vue判断input输入内容全是空格的方法
Mar 02 Javascript
微信小程序个人中心的列表控件实现代码
Apr 26 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分页显示制作详细讲解
2006/10/09 PHP
PHP 中英文混合排版中处理字符串常用的函数
2007/04/12 PHP
几款免费开源的不用数据库的php的cms
2010/12/19 PHP
php5.2以下版本无json_decode函数的解决方法
2014/05/25 PHP
php字符串分割函数用法实例
2015/03/17 PHP
简单的php+mysql聊天室实现方法(附源码)
2016/01/05 PHP
微信自定义分享php代码分析
2016/11/24 PHP
php 猴子摘桃的算法
2017/06/20 PHP
PHP+Ajax实现的无刷新分页功能详解【附demo源码下载】
2017/07/03 PHP
基于JQuery的一个简单的鼠标跟随提示效果
2010/09/23 Javascript
学习面向对象之面向对象的术语
2010/11/30 Javascript
js改变文章字体大小的实例代码
2013/11/27 Javascript
利用jQuary实现文字浮动提示效果示例代码
2013/12/26 Javascript
JQuery的Ajax中Post方法传递中文出现乱码的解决方法
2014/10/21 Javascript
jQuery中delegate()方法用法实例
2015/01/19 Javascript
jquery实现自适应banner焦点图
2017/02/16 Javascript
ionic2打包android时gradle无法下载的解决方法
2017/04/05 Javascript
nodejs项目windows下开机自启动的方法
2017/11/22 NodeJs
vue2.x+webpack快速搭建前端项目框架详解
2017/11/30 Javascript
原生JS实现动态加载js文件并在加载成功后执行回调函数的方法
2020/12/30 Javascript
jquery多级树形下拉菜单的实例代码
2019/07/09 jQuery
vue动态绘制四分之三圆环图效果
2019/09/03 Javascript
在SAE上部署Python的Django框架的一些问题汇总
2015/05/30 Python
python操作excel的方法(xlsxwriter包的使用)
2018/06/11 Python
Django框架之中间件MiddleWare的实现
2019/12/30 Python
解决Tensorflow 使用时cpu编译不支持警告的问题
2020/02/03 Python
Tensorflow 多线程设置方式
2020/02/06 Python
Python BeautifulReport可视化报告代码实例
2020/04/13 Python
Schutz鞋官方网站:Schutz Shoes
2017/12/13 全球购物
外贸采购员岗位职责
2014/03/08 职场文书
遵纪守法演讲稿
2014/05/23 职场文书
公务员诚信承诺书
2014/05/26 职场文书
2014年自愿离婚协议书
2014/10/10 职场文书
2019通用版导游词范本!
2019/08/07 职场文书
win10怎么设置右下角图标不折叠?Win10设置右下角图标不折叠的方法
2022/07/15 数码科技
react中useState使用:如何实现在当前表格直接更改数据
2022/08/05 Javascript