深入理解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 相关文章推荐
nicejforms——美化表单不用愁
Feb 20 Javascript
JS遮罩层效果 兼容ie firefox jQuery遮罩层
Jul 26 Javascript
JavaScript Math.floor方法(对数值向下取整)
Jan 09 Javascript
打造自己的jQuery插件入门教程
Sep 23 Javascript
基于Layer+jQuery的自定义弹框
May 26 Javascript
微信小程序 switch组件详解及简单实例
Jan 10 Javascript
Vue系列:通过vue-router如何传递参数示例
Jan 16 Javascript
JavaScript正则表达式校验与递归函数实际应用实例解析
Aug 04 Javascript
bootstrap confirmation按钮提示组件使用详解
Aug 22 Javascript
不使用JavaScript实现菜单的打开和关闭效果demo
May 01 Javascript
javascript 易错知识点实例小结
Apr 25 Javascript
js实现简单贪吃蛇游戏
May 15 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 使用GD库为页面增加水印示例代码
2014/03/24 PHP
PHP输出Excel PHPExcel的方法
2018/07/26 PHP
HR vs CL BO3 第二场 2.13
2021/03/10 DOTA
通过jquery实现tab标签浏览效果
2007/02/20 Javascript
面向对象的Javascript之二(接口实现介绍)
2012/01/27 Javascript
js工具方法弹出蒙版
2013/05/08 Javascript
JS实现一个按钮的方法
2015/02/05 Javascript
javascript实现一个数值加法函数
2015/06/26 Javascript
AngularJS 输入验证详解及实例代码
2016/07/28 Javascript
ionic组件ion-tabs选项卡切换效果实例
2016/08/27 Javascript
jQuery可见性过滤选择器用法示例
2016/09/09 Javascript
jQuery倒计时代码(超简单)
2017/02/27 Javascript
浅谈Angular4中常用管道
2017/09/27 Javascript
vue中使用localstorage来存储页面信息
2017/11/04 Javascript
前端Electron新手入门教程详解
2019/06/21 Javascript
详解Django中的form库的使用
2015/07/18 Python
Python实现读取txt文件并画三维图简单代码示例
2017/12/09 Python
深入浅析Python的类
2018/06/22 Python
浅析python3中的os.path.dirname(__file__)的使用
2018/08/30 Python
python爬虫获取新浪新闻教学
2018/12/23 Python
Python中new方法的详解
2019/01/15 Python
python实现蒙特卡罗方法教程
2019/01/28 Python
使用python绘制二元函数图像的实例
2019/02/12 Python
详解Python的三种可变参数
2019/05/08 Python
Python实现滑动平均(Moving Average)的例子
2019/08/24 Python
Python对Tornado请求与响应的数据处理
2020/02/12 Python
Python requests模块cookie实例解析
2020/04/14 Python
Django用内置方法实现简单搜索功能的方法
2020/12/18 Python
HTML5的video标签的浏览器兼容性增强方案分享
2016/05/19 HTML / CSS
法律专业个人实习自我鉴定
2013/09/23 职场文书
秋季红领巾广播稿
2014/01/27 职场文书
人事部岗位职责范本
2014/03/05 职场文书
庆祝教师节标语
2014/10/09 职场文书
维稳工作情况汇报
2014/10/27 职场文书
小程序wx.getUserProfile接口的具体使用
2021/06/02 Javascript
python可视化分析绘制带趋势线的散点图和边缘直方图
2022/06/25 Python