深入理解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 相关文章推荐
自用js开发框架小成 学习js的朋友可以看看
Nov 16 Javascript
javascript的数据类型、字面量、变量介绍
May 23 Javascript
解析使用js判断只能输入数字、字母等验证的方法(总结)
May 14 Javascript
js实现回放拖拽轨迹从过程上进行分析
Jun 26 Javascript
JS 对java返回的json格式的数据处理方法
Dec 05 Javascript
js转换对象为xml
Feb 17 Javascript
vue.js实现备忘录功能的方法
Jul 10 Javascript
AngularJS中重新加载当前路由页面的方法
Mar 09 Javascript
js中async函数结合promise的小案例浅析
Apr 14 Javascript
使用layui实现的左侧菜单栏以及动态操作tab项方法
Sep 10 Javascript
Vue的全局过滤器和私有过滤器的实现
Apr 20 Javascript
Node.js 中判断一个文件是否存在
Aug 24 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切割页面div内容的实现代码分享
2012/07/31 PHP
smarty简单分页的实现方法
2014/10/27 PHP
javascript some()函数用法详解
2014/11/13 PHP
从面试题学习Javascript 面向对象(创建对象)
2012/03/30 Javascript
JavaScript原型链示例分享
2014/01/26 Javascript
常用的JavaScript模板引擎介绍
2015/02/28 Javascript
jQuery插件slicebox实现3D动画图片轮播切换特效
2015/04/12 Javascript
jquery插件Jplayer使用方法简析
2016/04/22 Javascript
瀑布流的实现方式(原生js+jquery+css3)
2020/06/28 Javascript
EasyUI创建对话框的两种方式
2016/08/23 Javascript
微信小程序 详解下拉加载与上拉刷新实现方法
2017/01/13 Javascript
Bootstrap按钮组简单实现代码
2017/03/06 Javascript
Vue-cli配置打包文件本地使用的教程图解
2018/08/02 Javascript
详解微信小程序canvas圆角矩形的绘制的方法
2018/08/22 Javascript
vue实现简单的星级评分组件源码
2018/11/16 Javascript
jquery无缝图片轮播组件封装
2020/11/25 jQuery
Vue实现商品飞入购物车效果(电商项目)
2019/11/26 Javascript
JavaScript 替换所有匹配内容及正则替换方法
2020/02/12 Javascript
react国际化化插件react-i18n-auto使用详解
2020/03/31 Javascript
[39:08]完美世界DOTA2联赛PWL S3 LBZS vs CPG 第一场 12.12
2020/12/16 DOTA
Python定时发送消息的脚本:每天跟你女朋友说晚安
2018/10/21 Python
TensorFlow:将ckpt文件固化成pb文件教程
2020/02/11 Python
基于Python脚本实现邮件报警功能
2020/05/20 Python
Python嵌入C/C++进行开发详解
2020/06/09 Python
django和flask哪个值得研究学习
2020/07/31 Python
基于html5绘制圆形多角图案
2016/04/21 HTML / CSS
Nike法国官方网站:Nike.com FR
2018/07/22 全球购物
广告学专业毕业生自荐信
2013/09/24 职场文书
社区党总支书记先进事迹材料
2014/01/24 职场文书
最新奶茶店创业计划书范文
2014/02/08 职场文书
员工廉洁自律承诺书
2014/05/26 职场文书
毕业论文致谢信
2015/05/14 职场文书
golang switch语句的灵活写法介绍
2021/05/06 Golang
Django实现在线无水印抖音视频下载(附源码及地址)
2021/05/06 Python
PyTorch dropout设置训练和测试模式的实现
2021/05/27 Python
React四级菜单的实现
2022/04/08 Javascript