深入理解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 相关文章推荐
SWFObject Flash js调用类
Jul 08 Javascript
Ubuntu 11.10 安装Node.js的方法
Nov 30 Javascript
JSCode all of Brower 全局屏蔽网页右键功能 具体实现
Jun 05 Javascript
仿百度联盟对联广告实现代码
Aug 30 Javascript
AngularJS入门教程(一):静态模板
Dec 06 Javascript
使用Node.js为其他程序编写扩展的基本方法
Jun 23 Javascript
jQuery Easyui datagrid editor为combobox时指定数据源实例
Dec 19 Javascript
详解vue父子组件间传值(props)
Jun 29 Javascript
js防刷新的倒计时代码 js倒计时代码
Sep 06 Javascript
微信小程序实现商城倒计时
Nov 01 Javascript
微信小程序实现张图片合成为一张并下载
Jul 16 Javascript
在VUE中实现文件下载并判断状态的方法
Nov 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
十天学会php之第一天
2006/10/09 PHP
mayfish 数据入库验证代码
2010/04/30 PHP
php+jQuery+Ajax实现点赞效果的方法(附源码下载)
2020/07/21 PHP
PHP使用strstr()函数获取指定字符串后所有字符的方法
2016/01/07 PHP
Laravel 5.3 学习笔记之 错误&日志
2016/08/28 PHP
10个基于jQuery或JavaScript的WYSIWYG 编辑器整理
2010/05/06 Javascript
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
2010/06/28 Javascript
js动态创建、删除表格示例代码
2013/08/07 Javascript
java与javascript之间json格式数据互转介绍
2013/10/29 Javascript
js获得页面的高度和宽度的方法
2014/02/23 Javascript
jquery数组过滤筛选方法grep()简介
2014/06/06 Javascript
jQuery html()方法使用不了无法显示内容的问题
2014/08/06 Javascript
Javascript使用uploadify来实现多文件上传
2016/11/16 Javascript
vue-resourse将json数据输出实例
2017/03/08 Javascript
JavaScript文件的同步和异步加载的实现代码
2017/08/19 Javascript
纯JS实现的读取excel文件内容功能示例【支持所有浏览器】
2018/06/23 Javascript
jQuery 操作 HTML 元素和属性的方法
2018/11/12 jQuery
VSCode插件安装完成后的配置(常用配置)
2020/08/24 Javascript
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
2018/02/10 Python
Python OS模块实例详解
2019/04/15 Python
python networkx 根据图的权重画图实现
2019/07/10 Python
python使用itchat模块给心爱的人每天发天气预报
2019/11/25 Python
用Python绘制漫步图实例讲解
2020/02/26 Python
详解python中的三种命令行模块(sys.argv,argparse,click)
2020/12/15 Python
美国皮靴公司自1863年:The Frye Company
2016/11/30 全球购物
linux面试题参考答案(10)
2013/11/04 面试题
2014年党员公开承诺书范文
2014/03/28 职场文书
计算机专业毕业生求职信
2014/04/30 职场文书
村抢险救灾方案
2014/05/09 职场文书
毕业生实习期转正自我鉴定
2014/09/26 职场文书
2015年师德师风承诺书
2015/01/22 职场文书
大明湖导游词
2015/02/03 职场文书
JavaScript+HTML实现学生信息管理系统
2021/04/20 Javascript
深入浅析Redis 集群伸缩原理
2021/05/15 Redis
Python一行代码实现自动发邮件功能
2021/05/30 Python
Apache Hudi数据布局黑科技降低一半查询时间
2022/03/31 Servers