深入理解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 相关文章推荐
一个用js实现的页内搜索代码
May 23 Javascript
JS option location 页面跳转实现代码
Dec 27 Javascript
js 获取坐标 通过JS得到当前焦点(鼠标)的坐标属性
Jan 04 Javascript
JS可以控制样式的名称写法一览
Jan 16 Javascript
jquery获取当前点击对象的value方法
Feb 28 Javascript
Angularjs制作简单的路由功能demo
Apr 14 Javascript
JS延时提示框实现方法详解
Nov 26 Javascript
js实现继承的5种方式
Dec 01 Javascript
jQuery Validate初步体验(一)
Dec 12 Javascript
利用jquery禁止外层滚动条的滚动
Jan 05 Javascript
js实现一个猜数字游戏
Mar 31 Javascript
JS和Canvas实现图片的预览压缩和上传功能
Mar 30 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 strnatcmp()函数的用法总结
2013/11/27 PHP
ThinkPHP实现将SESSION存入MYSQL的方法
2014/07/22 PHP
WordPress中给文章添加自定义字段及后台编辑功能区域
2015/12/19 PHP
js实现页面打印功能实例代码(附去页眉页脚功能代码)
2009/12/15 Javascript
js 居中漂浮广告
2010/03/21 Javascript
JavaScript禁止页面操作的示例代码
2013/12/17 Javascript
Ext修改GridPanel数据和字体颜色、css属性等
2014/06/13 Javascript
js实现文字跟随鼠标移动而移动的方法
2015/02/28 Javascript
原生JS封装ajax 传json,str,excel文件上传提交表单(推荐)
2016/06/21 Javascript
js实现可输入可选择的select下拉框
2016/12/21 Javascript
详解vue服务端渲染(SSR)初探
2017/06/19 Javascript
javascript 中模板方法单例的实现方法
2017/10/17 Javascript
微信小程序如何获取用户收货地址
2018/11/27 Javascript
微信小程序module.exports模块化操作实例浅析
2018/12/20 Javascript
vue组件通信传值操作示例
2019/01/08 Javascript
JS实现轮播图效果
2020/01/11 Javascript
Vue循环遍历选项赋值到对应控件的实现方法
2020/06/22 Javascript
javascript实现前端input密码输入强度验证
2020/06/24 Javascript
python在windows下实现备份程序实例
2014/07/04 Python
Python使用Dijkstra算法实现求解图中最短路径距离问题详解
2018/05/16 Python
Python之两种模式的生产者消费者模型详解
2018/10/26 Python
python实现求特征选择的信息增益
2018/12/18 Python
python中pygame安装过程(超级详细)
2019/08/04 Python
Python全栈之列表数据类型详解
2019/10/01 Python
flask利用flask-wtf验证上传的文件的方法
2020/01/17 Python
使用TensorFlow直接获取处理MNIST数据方式
2020/02/10 Python
浅谈Python中的生成器和迭代器
2020/06/19 Python
深入了解NumPy 高级索引
2020/07/24 Python
Python如何发送与接收大型数组
2020/08/07 Python
纯CSS3代码实现switch滑动开关按钮效果
2016/08/30 HTML / CSS
宝拉珍选官方旗舰店:2%水杨酸精华液,收缩毛孔粗大和祛痘
2018/07/01 全球购物
英国女装网上商店:I Saw It First
2018/10/18 全球购物
酒店管理专业自荐信
2014/05/23 职场文书
考试作弊被抓检讨书
2014/10/02 职场文书
关于车尾的标语大全
2015/08/11 职场文书
2016年感恩母亲节活动总结
2016/04/01 职场文书