深入理解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压缩工具下载集合
Mar 06 Javascript
RGB颜色值转HTML十六进制(HEX)代码的JS函数
Apr 25 Javascript
jQuery 判断元素上是否绑定了事件
Oct 28 Javascript
利用javaScript实现点击输入框弹出窗体选择信息
Dec 11 Javascript
js调试系列 控制台命令行API使用方法
Jun 18 Javascript
jQuery中:visible选择器用法实例
Dec 30 Javascript
jQuery实现模仿微博下拉滚动条加载数据效果
Dec 25 Javascript
JS中判断字符串中出现次数最多的字符及出现的次数的简单实例
Jun 03 Javascript
JS弹出新窗口被拦截的解决方法
Aug 09 Javascript
Angular的$http的ajax的请求操作(推荐)
Jan 10 Javascript
vue实现动态显示与隐藏底部导航的方法分析
Feb 11 Javascript
微信小程序bindtap事件与冒泡阻止详解
Aug 08 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
基于JQuery+PHP编写砸金蛋中奖程序
2015/09/08 PHP
mysql desc(DESCRIBE)命令实例讲解
2016/09/24 PHP
基于php+MySql实现学生信息管理系统实例
2020/08/04 PHP
用jQuery实现检测浏览器及版本的脚本代码
2008/01/22 Javascript
javascript获得CheckBoxList选中的数量
2009/10/27 Javascript
教您去掉ie网页加载进度条的方法
2010/12/09 Javascript
Js 冒泡事件阻止实现代码
2013/01/27 Javascript
js获取select标签的值且兼容IE与firefox
2013/12/30 Javascript
PHP中CURL的几个经典应用实例
2015/01/23 Javascript
微信小程序 form组件详解
2016/10/25 Javascript
JS/jQuery判断DOM节点是否存在的简单方法
2016/11/24 Javascript
js代码实现下拉菜单【推荐】
2016/12/15 Javascript
微信小程序 tabs选项卡效果的实现
2017/01/05 Javascript
Node.js+jade抓取博客所有文章生成静态html文件的实例
2017/09/19 Javascript
JavaScript数组去重的几种方法
2019/04/07 Javascript
JS求1到任意数之间的所有质数的方法详解
2019/05/20 Javascript
微信小程序如何利用getCurrentPages进行页面传值
2019/07/01 Javascript
Scrapy-redis爬虫分布式爬取的分析和实现
2017/02/07 Python
Python实现的异步代理爬虫及代理池
2017/03/17 Python
Python网络编程 Python套接字编程
2017/09/13 Python
详解python异步编程之asyncio(百万并发)
2018/07/07 Python
Flask框架使用DBUtils模块连接数据库操作示例
2018/07/20 Python
windows下搭建python scrapy爬虫框架步骤
2018/12/23 Python
pandas.cut具体使用总结
2019/06/24 Python
python线程安全及多进程多线程实现方法详解
2019/09/27 Python
tensorflow实现tensor中满足某一条件的数值取出组成新的tensor
2020/01/04 Python
html5实现的便签特效(实战分享)
2013/11/29 HTML / CSS
Otticanet澳大利亚:最顶尖的世界名牌眼镜, 能得到打折季的价格
2018/08/23 全球购物
Marlies Dekkers内衣美国官方网上商店:高端内衣品牌
2018/11/12 全球购物
精选奢华:THE LIST
2019/09/05 全球购物
最畅销的视频游戏享受高达90%的折扣:CDKeys
2020/02/10 全球购物
竞选村长演讲稿
2014/04/28 职场文书
学生违反校规检讨书
2014/10/28 职场文书
检讨书大全
2015/01/27 职场文书
2015年社区工会工作总结
2015/05/26 职场文书
预备党员介绍人意见
2015/06/01 职场文书