深入理解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(一)jquery选择符 必备知识点
Nov 25 Javascript
鼠标滑在标题上显示图片的JS代码
Nov 19 Javascript
jquery 隐藏与显示tr标签示例代码
Jun 06 Javascript
jQuery实现炫酷的鼠标轨迹特效
Feb 01 Javascript
JS控制FileUpload的上传文件类型实例代码
Oct 07 Javascript
js实现抽奖效果
Mar 27 Javascript
详谈jQuery中使用attr(), prop(), val()获取value的异同
Apr 25 jQuery
vue弹窗消息组件的使用方法
Sep 24 Javascript
JS实现监控微信小程序的原理
Jun 15 Javascript
vue-cli2.x项目优化之引入本地静态库文件的方法
Jun 19 Javascript
VUE 实现复制内容到剪贴板的两种方法
Apr 24 Javascript
vue 递归组件的简单使用示例
Jan 14 Vue.js
深入理解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中英混合字符串截取函数代码
2011/07/17 PHP
php中使用Imagick实现图像直方图的实现代码
2011/08/30 PHP
查找mysql字段中固定字符串并替换的几个方法
2012/09/23 PHP
EarthLiveSharp中cloudinary的CDN图片缓存自动清理python脚本
2017/04/04 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
2017/07/03 PHP
zTree插件之多选下拉菜单实例代码
2013/11/06 Javascript
js面向对象之公有、私有、静态属性和方法详解
2015/04/17 Javascript
JS实现消息来时让网页标题闪动效果的方法
2016/04/20 Javascript
Bootstrap每天必学之折叠(Collapse)插件
2016/04/25 Javascript
jquery 多个radio的click事件实例
2016/12/03 Javascript
JS 循环li添加点击事件 (闭包的应用)
2016/12/10 Javascript
jQuery Validate表单验证插件实现代码
2017/06/08 jQuery
Vue 实现树形视图数据功能
2018/05/07 Javascript
Babel 入门教程学习笔记
2018/06/13 Javascript
angular中两种表单的区别(响应式和模板驱动表单)
2018/12/06 Javascript
微信小程序基础教程之worker线程的使用方法
2019/07/15 Javascript
小程序自定义导航栏兼容适配所有机型(附完整案例)
2020/04/26 Javascript
[01:15:36]加油刀塔第二期网络版
2014/08/09 DOTA
pycharm 使用心得(七)一些实用功能介绍
2014/06/06 Python
python开发中range()函数用法实例分析
2015/11/12 Python
Python pandas常用函数详解
2018/02/07 Python
Pycharm无法使用已经安装Selenium的解决方法
2018/10/13 Python
python用插值法绘制平滑曲线
2021/02/19 Python
python实现QQ邮箱/163邮箱的邮件发送
2019/01/22 Python
python实现LBP方法提取图像纹理特征实现分类的步骤
2019/07/11 Python
Django 静态文件配置过程详解
2019/07/23 Python
使用Jupyter notebooks上传文件夹或大量数据到服务器
2020/04/14 Python
Python调用C语言程序方法解析
2020/07/07 Python
咖啡厅创业计划书范本
2014/01/22 职场文书
《草原》教学反思
2014/02/15 职场文书
社会治安综合治理责任书
2015/01/29 职场文书
搞笑老公保证书
2015/02/26 职场文书
高中生思想道德自我评价
2015/03/09 职场文书
借钱欠条怎么写
2015/07/03 职场文书
「睡美人」爱洛公主粘土人开订
2022/03/22 日漫
详解使用内网穿透工具Ngrok代理本地服务
2022/03/31 Servers