javascript设计模式与开发实践阅读笔记(11)—— 模板方法模式
模板方法模式:
由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序。子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。
泡咖啡和泡茶的例子
var Coffee = function(){}; //作为构造函数
Coffee.prototype.boilWater = function(){
console.log( '把水煮沸' );
};
Coffee.prototype.brewCoffeeGriends = function(){
console.log( '用沸水冲泡咖啡' );
};
Coffee.prototype.pourInCup = function(){
console.log( '把咖啡倒进杯子' );
};
Coffee.prototype.addSugarAndMilk = function(){
console.log( '加糖和牛奶' );
};
Coffee.prototype.init = function(){
this.boilWater(); //煮水
this.brewCoffeeGriends(); //泡咖啡
this.pourInCup(); //倒进杯子
this.addSugarAndMilk(); //加糖和牛奶
};
var coffee = new Coffee(); //实例一个“咖啡”对象
coffee.init(); //调用
var Tea = function(){}; //作为构造函数
Tea.prototype.boilWater = function(){
console.log( '把水煮沸' );
};
Tea.prototype.steepTeaBag = function(){
console.log( '用沸水浸泡茶叶' );
};
Tea.prototype.pourInCup = function(){
console.log( '把茶水倒进杯子' );
};
Tea.prototype.addLemon = function(){
console.log( '加柠檬' );
};
Tea.prototype.init = function(){
this.boilWater(); //煮水
this.steepTeaBag(); //泡茶
this.pourInCup(); //倒进杯子
this.addLemon(); //加柠檬
};
var tea = new Tea(); //实例一个“茶”对象
tea.init(); //调用
观察两段代码,发现其实他们是大同小异的,那我们完全可以把公共的部分抽象出来,作为一个抽象的父类模板
var drink=function(){} //作为抽象的构造类
drink.prototype.boilWater=function(){
console.log( '把水煮沸' );
}
drink.prototype.brew=function(){}; //空方法,用来给模板套用
drink.prototype.pourInCup = function(){}; // 同上
drink.prototype.addCondiments = function(){}; // 同上
drink.prototype.init = function(){ //模板在这里,重复的事情放在模板里
this.boilWater();
this.brew();
this.pourInCup();
this.addCondiments();
};
然后就是具体的咖啡类和茶类
/**创建咖啡类**/
var Coffee = function(){}; //这是一个具体的类,作为构造函数存在
Coffee.prototype = new drink(); //把构造函数的prototype指向抽象类的实例 Coffee.prototype.brew = function(){
console.log( '用沸水冲泡咖啡' );
};
Coffee.prototype.pourInCup = function(){
console.log( '把咖啡倒进杯子' );
};
Coffee.prototype.addCondiments = function(){
console.log( '加糖和牛奶' );
}; var coffee = new Coffee(); //新建咖啡实例
coffee.init(); //调用模板
/*结果*/
//把水煮沸
//用沸水冲泡咖啡
//把咖啡倒进杯子
//加糖和牛奶
/**创建茶类**/
var Tea = function(){}; //具体的类,作为构造函数
Tea.prototype = new drink(); //把构造函数的prototype指向抽象类的实例 Tea.prototype.brew = function(){
console.log( '用沸水浸泡茶叶' );
};
Tea.prototype.pourInCup = function(){
console.log( '把茶倒进杯子' );
};
Tea.prototype.addCondiments = function(){
console.log( '加柠檬' );
}; var tea = new Tea(); //新建茶实例
tea.init(); //调用模板
/*结果*/
//把水煮沸
//用沸水浸泡茶叶
//把茶倒进杯子
//加柠檬
使用es6的话,代码可以简洁不少
class drink{ //抽象模板父类
boilWater(){
console.log("把水煮沸");
};
brew(){};
pourInCup(){};
addCondiments(){};
init(){
this.boilWater();
this.brew();
this.pourInCup();
this.addCondiments();
}
}
class Coffee extends drink{ //具体的类,内部重写相应方法
brew(){
console.log("用沸水冲泡咖啡");
}
pourInCup(){
console.log( '把咖啡倒进杯子' );
}
addCondiments(){
console.log( '加糖和牛奶' );
}
}
var coffee=new Coffee(); //实例
coffee.init(); //把水煮沸
//用沸水冲泡咖啡
//把咖啡倒进杯子
//加糖和牛奶
js实现模板模式的一些问题
我们在抽象父类中提供了模板,在具体的类中重写相应的方法,但是这个过程全靠程序员的自觉和记忆,语言层面并没有提供任何检查,如果我们忘了重写相应的方法,js也不会报错。
一种解决方案是用鸭子类型来模拟接口检查,缺点就是会带来很多不必要的复杂性,增加很多和业务无关的代码。
另一种解决方案是抽象父类中的相应抽象方法里都抛出错误,如果子类没有重写相应方法,运行时就会报错,如下:
drink.prototype.brew=function(){
throw new Error( '子类必须重写brew 方法' );
};
钩子方法
可以增加自由度,有的子类并不适合把模板方法全部运行,钩子方法可以让子类自行决定是否执行对应的模板方法。
drink.prototype.add=function(){ //钩子方法,子类中可以改写,模板方法中会进行判断
return true; //默认为true,用于判断
}
drink.prototype.init = function(){ //模板方法
this.boilWater();
this.brew();
this.pourInCup();
if( this.add() ){ //如果挂钩返回true,则需要调料
this.addCondiments();
}
};
javascript设计模式与开发实践阅读笔记(11)—— 模板方法模式的更多相关文章
- javascript设计模式与开发实践阅读笔记(4)——单例模式
定义 单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 具体来说,就是保证有些对象有且只有一个,比如线程池.全局缓存.浏览器中的window 对象等.在js中单例模式用途很广,比如登录 ...
- javascript设计模式与开发实践阅读笔记(8)——观察者模式
发布-订阅模式,也叫观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 在JavaScript开发中,我们一般用事件模型来替代传统的观察者模式. ...
- javascript设计模式与开发实践阅读笔记(7)——迭代器模式
迭代器模式:指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺 ...
- javascript设计模式与开发实践阅读笔记(6)——代理模式
代理模式:是为一个对象提供一个代用品或占位符,以便控制对它的访问. 代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对 ...
- javascript设计模式与开发实践阅读笔记(5)——策略模式
策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 我的理解就是把各种方法封装成函数,同时存在一个可以调用这些方法的公共函数.这样做的好处是可以消化掉内部的分支判断,使代码效率 ...
- javascript设计模式与开发实践阅读笔记(9)——命令模式
命令模式:有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么,此时希望用一种松耦合的方式来设计软件,使得请求发送者和请求接收者能够消除彼此之间的耦合关系. 说法很复 ...
- JavaScript设计模式与开发实践——读书笔记1.高阶函数(上)
说来惭愧,4个多月未更新了.4月份以后就开始忙起来了,论文.毕设.毕业旅行等七七八八的事情占据了很多时间,毕业之后开始忙碌的工作,这期间一直想写博客,但是一直没能静下心写.这段时间在看<Java ...
- 《JavaScript设计模式与开发实践》笔记第八章 发布-订阅模式
第八章 发布-订阅模式 发布-订阅模式描述 发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 发布-订阅模式可以广泛应用于 ...
- JavaScript设计模式与开发实践——读书笔记1.高阶函数(下)
上部分主要介绍高阶函数的常见形式,本部分将着重介绍高阶函数的高级应用. 1.currying currying指的是函数柯里化,又称部分求值.一个currying的函数会先接受一些参数,但不立即求值, ...
随机推荐
- 控制流之for
for..in是另外一个循环语句,它在一序列的对象上 递归 即逐一使用队列中的每个项目.我们会在后面的章节中更加详细地学习序列.使用for语句~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- (简单) POJ 3321 Apple Tree,树链剖分+树状数组。
Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow ...
- Java对文件的16进制读取和操作
大家可以参考一下源代码的相关部分注释,然后写出自己的16进制处理程序.有几个重点地方: 16进制字符串->10进制数 int input = Integer.parseInt("Str ...
- Rest之路 -- 从第二个Rest application里面分析 Rest 方法
引言 在此之前,我们实现了第一个Rest application,通过分析她,我们了解了 Rest 程序的基本要素:这里,我们将会对第一个 Rest application 的功能进行扩充(实现 CR ...
- 10天学会phpWeChat——第八天:Form类,丰富表单提交的字段类型
通过前面七讲的系列教程,我们完成了一个包含后台并自适应PC+h5移动端的文章管理模块. 在实际的生产环境中,文章投稿.商品上传等操作并不会简单局限于一个text和textarea组成的表单.在实际中, ...
- NSDate详解及获取当前时间等常用操作
NSDate类用于保存时间值,同时提供了一些方法来处理一些基于秒级别时差(Time Interval)运算和日期之间的早晚比较等. 1. 创建或初始化可用以下方法 用于创建NSDate实例的类方法有 ...
- Python3基础 set() 集合 创建集合与特点:自动将重复合并掉 不支持索引
镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...
- 把windows的bat用好了,也很不错
taskkill /f /t /im nginx.exe cp2nginx xcopy /e /i /y “D:\workspace\workspace1\aff\WebContent” “D:\ng ...
- error: Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier
xcode + iwatch调试错误 在工程的 Targets 下面的 三项(工程名为my):my . my Watchkit app .my Watchkit extention General ...
- mysql 视图示例
基本操作 建立视图 CREATE VIEW view_test(qty,price,total) AS SELECT quantity,price,quantity*price FROM t; 多表视 ...