深入理解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——表单应用范例
Feb 20 Javascript
转义字符(\)对JavaScript中JSON.parse的影响概述
Jul 17 Javascript
基于JQuery的列表拖动排序实现代码
Oct 01 Javascript
深入理解Javascript里的依赖注入
Mar 19 Javascript
jquery获取tagName再进行判断
May 29 Javascript
form.submit()不能提交表单的原因分析
Oct 23 Javascript
jQuery实现Div拖动+键盘控制综合效果的方法
Mar 10 Javascript
jQuery实现仿Alipay支付宝首页全屏焦点图切换特效
May 04 Javascript
用JS写的一个Ajax库(实例代码)
Aug 06 Javascript
轻松理解vue的双向数据绑定问题
Oct 30 Javascript
vue实现点击按钮“查看详情”弹窗展示详情列表操作
Sep 09 Javascript
ES11屡试不爽的新特性,你用上了几个
Oct 21 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实现用户认证及管理完全源码
2007/03/11 PHP
php中处理mysql_fetch_assoc返回来的数组 不用foreach----echo
2011/05/04 PHP
CentOS 7.2 下编译安装PHP7.0.10+MySQL5.7.14+Nginx1.10.1的方法详解(mini版本)
2016/09/01 PHP
浅谈PHP的反射API
2017/02/26 PHP
ThinkPHP like模糊查询,like多匹配查询,between查询,in查询,一般查询书写方法
2018/09/26 PHP
CentOS7.0下安装PHP5.6.30服务的教程详解
2018/09/29 PHP
PHP ajax+jQuery 实现批量删除功能实例代码小结
2018/12/06 PHP
通过Jquery的Ajax方法读取将table转换为Json
2014/05/31 Javascript
js实现文本框支持加减运算的方法
2015/08/19 Javascript
jQuery语法小结(超实用)
2015/12/31 Javascript
select隐藏选中值对应的id,显示其它id的简单实现方法
2016/08/25 Javascript
深入理解AngularJS中的ng-bind-html指令和$sce服务
2016/09/08 Javascript
js实现加载页面就自动触发超链接的示例
2017/08/31 Javascript
jquery ztree实现右键收藏功能
2017/11/20 jQuery
JS实现关键词高亮显示正则匹配
2018/06/22 Javascript
js实现延迟加载的几种方法详解
2019/01/19 Javascript
下载给定网页上图片的方法
2014/02/18 Python
Python读取Pickle文件信息并计算与当前时间间隔的方法分析
2019/01/30 Python
python pexpect ssh 远程登录服务器的方法
2019/02/14 Python
Django自定义模板过滤器和标签的实现方法
2019/08/21 Python
python爬虫 正则表达式解析
2019/09/28 Python
OpenCV+Python--RGB转HSI的实现
2019/11/27 Python
Python selenium抓取虎牙短视频代码实例
2020/03/02 Python
python初步实现word2vec操作
2020/06/09 Python
Python Switch Case三种实现方法代码实例
2020/06/18 Python
京东港澳售:京东直邮港澳台
2018/01/31 全球购物
联想智利官方网站:Lenovo Chile
2020/06/03 全球购物
意大利在线药房:Saninforma
2021/02/11 全球购物
优秀医生事迹材料
2014/02/12 职场文书
行政部岗位职责范本
2014/03/13 职场文书
人力资源管理专业毕业生自荐书
2014/05/25 职场文书
个人四风问题对照检查材料
2014/10/01 职场文书
导盲犬小Q观后感
2015/06/11 职场文书
浅谈Mysql多表连接查询的执行细节
2021/04/24 MySQL
vue+spring boot实现校验码功能
2021/05/27 Vue.js
SQL语句中JOIN的用法场景分析
2021/07/25 SQL Server