轻松掌握:JavaScript模板方法模式
模板方法模式
假如我们有一些对象,各个对象之间有一些相同的行为,也有一些不同的行为,这时,我们就可以用模板方法模式来把相同的部分上移到它们的共同原型中(父类),而将不同的部分留给自己各自重新实现。
模板方法:在这些平行对象的共同原型中定义的一个方法,它封装了子类的算法框架,它作为一个算法的模板,指导子类以何种顺序去执行哪些方法。
模板方法常常被架构师用于搭建项目的框架,架构师定好了框架的骨架,程序员们继承框架的结构后,负责往里面填空。
模板方法模式中,常常用到一个钩子方法:在父类中的容易变化的方法上放置钩子,模板方法依据钩子方法的返回值来决定是否执行容易变化的方法。
模板方法模式是一种基于继承的设计模式,但在JavaScript中也可以通过高阶函数来实现。
基于继承的模板方法模式:
//模板方法模式
//泡茶和冲咖啡,有相似的方法,也有不同的方法
//相似的方法在父类中实现,不同的方法在子类中各自重写
var Beverage = function () {};
Beverage.prototype.boilWater = function () {
console.log('把水煮沸');
};
Beverage.prototype.pourMaterial = function (material) {
console.log('把'+material+'倒进杯子');
};
Beverage.prototype.pourInCup = function () {
console.log('把沸水倒进杯子');
};
Beverage.prototype.addCondiments = function () {
throw new Error('子类必须自行实现该方法');
};
//钩子方法,是否需要加配料
Beverage.prototype.isWantCondiments = function () {
return true; //默认为true,子类自行实现来改变返回值
};
//模板方法,规定了各个方法的执行顺序
Beverage.prototype.init = function (material) {
this.boilWater();
this.pourMaterial(material);
this.pourInCup();
if(this.isWantCondiments()){ //根据钩子方法的返回值决定是否执行
this.addCondiments();
}
};
//====子类
var Coffee = function () {};
Coffee.prototype = new Beverage(coffee);
Coffee.prototype.addCondiments = function () {
console.log('加糖');
};
Coffee.prototype.isWantCondiments = function () {
return window.confirm('请问需要加糖吗?');
};
//调用
var coffee = '咖啡粉';
var coffee1 = new Coffee();
coffee1.init(coffee);
通过高阶函数来实现:
var Beverage1 = function (obj,material) {
var boilWater = function(){
console.log('把水煮沸');
};
var pourMaterial = function(material){
console.log('把'+material+'倒进杯子');
};
var pourInCup = function () {
console.log('把沸水倒进杯子');
};
var addCondiments = obj.addCondiments||function () {
throw new Error('子类必须自行实现该方法');
};
var isWantCondiments = obj.isWantCondiments||function () {
return true; //默认为true,子类自行实现来改变返回值
};
var F = function(){};
F.prototype.init = function(){
boilWater();
pourMaterial(material);
pourInCup();
if(isWantCondiments()){ //根据钩子方法的返回值决定是否执行
addCondiments();
}
};
return F;
};
//定义子类
var Coffee1 = Beverage1({
addCondiments: function(){
console.log('加糖');
},
isWantCondiments: function () {
return window.confirm('请问需要加糖吗?');
}
},'咖啡粉');
var Tea1 = Beverage1({
addCondiments: function(){
console.log('加柠檬');
},
isWantCondiments: function () {
return window.confirm('请问需要加柠檬吗?');
}
},'茶叶');
var aCupOfCoffee = new Coffee1();
aCupOfCoffee.init();
//把水煮沸
//把咖啡粉倒进杯子
//把沸水倒进杯子
//加糖(点确定)
var aCupOfTea = new Tea1();
aCupOfTea.init();
//把水煮沸
//把茶叶倒进杯子
//把沸水倒进杯子
//加柠檬(点确定)
参考文献: 《JavaScript模式》 《JavaScript设计模式与开发实践》
轻松掌握:JavaScript模板方法模式的更多相关文章
- javascript模板方法模式
一:什么是模板方法模式: 模板方法模式由二部分组成,第一部分是抽象父类,第二部分是具体实现的子类,一般的情况下是抽象父类封装了子类的算法框架,包括实现一些公共方法及封装子类中所有方法的执行顺序,子类可 ...
- 《JavaScript设计模式与开发实践》读书笔记之模板方法模式
1. 模板方法模式 1.1 面向对象方式实现模板方法模式 以泡茶和泡咖啡为例,可以整理为下面四步 把水煮沸 用沸水冲泡饮料 把饮料倒进杯子 加调料 首先创建一个抽象父类来表示泡一杯饮料 var Bev ...
- 再起航,我的学习笔记之JavaScript设计模式17(模板方法模式)
模板方法模式 由模板方法模式开始我们正式告别结构型设计模式,开始行为型设计模式的学习分享 行为型设计模式用于不同对象之间职责划分或算法抽象,行为型设计模式不仅仅涉及类和对象,还涉及类或对象之间的交流模 ...
- javascript设计模式——模板方法模式
前面的话 在javascript开发中用到继承的场景其实并不是很多,很多时候喜欢用mix-in的方式给对象扩展属性.但这不代表继承在javascript里没有用武之地,虽然没有真正的类和继承机制,但可 ...
- JavaScript设计模式-----模板方法模式
模板方法模式是一种只需要使用继承就可以实现的非常简单点的模式. 模板方法模式有两部分组成,第一部分是抽象父类,第二部分是具体的实现子类.通常在抽象父类中封装了子类的算法框架,包括实现 一些公共方法以及 ...
- [设计模式] javascript 之 模板方法模式
模板方法模式说明 定义:定义方法操作的骨架,把一些具体实现延伸到子类中去,使用得具体实现不会影响到骨架的行为步骤! 说明:模式方法模式是一个继承跟复用的典型模式,该模式定义了一个抽象类,Abstrac ...
- javascript设计模式与开发实践阅读笔记(11)—— 模板方法模式
模板方法模式: 由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类.通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序.子类通过继承这个抽象类,也继 ...
- javascript设计模式(张容铭)学习笔记 - 照猫画虎-模板方法模式
模板方法模式(Template Method):父类中定义一组操作算法骨架,而降一些实现步骤延迟到子类中,使得子类可以不改变父类的算法结构的同时可重新定义算法中某些实现步骤. 项目经理体验了各个页面的 ...
- PHP设计模式之模板方法模式
模板方法模式,也是我们经常会在不经意间有会用到的模式之一.这个模式是对继承的最好诠释.当子类中有重复的动作时,将他们提取出来,放在父类中进行统一的处理,这就是模板方法模式的最简单通俗的解释.就像我们平 ...
随机推荐
- 以Excel 作为Data Source,将data导入db
将Excel作为数据源,将数据导入db,是SSIS的一个简单的应用,下图是示例Excel,数据列是code和name 第一部分,Excel中的数据类型是数值类型 1,使用SSDT创建一个package ...
- Sql Server系列:聚合函数
1 SUM SUM是一个求和函数,返回指定列值的总和.SUM 只能用于数字列. 其中忽略 Null 值. 语法 SUM ( [ ALL | DISTINCT ] expression ) OVER ( ...
- 前端学PHP之函数
× 目录 [1]函数定义 [2]函数参数[3]返回值[4]变量函数[5]回调函数[6]递归函数[7]加载函数[8]匿名函数 前面的话 PHP 的真正力量来自它的函数:它拥有超过 1000 个内建的函数 ...
- javascript运动系列第六篇——轨迹和投掷
× 目录 [1]运动轨迹 [2]拖拽轨迹 [3]投掷 前面的话 一般地,不同的运动形式会产生不同的轨迹.但仅凭肉眼去识别运动轨迹,其实并不是很直观.因此,在页面中显示运动轨迹,是一个重要的问题.物体初 ...
- NFS Volume Provider(Part II) - 每天5分钟玩转 OpenStack(63)
上一节我们将 NFS volume provider 配置就绪,本节将创建 volume. 创建 volume 创建 NFS volume 操作方法与 LVM volume 一样,唯一区别是在 vol ...
- HTML5 视频(二) <video> 使用 DOM 进行控制
HTML5 <video> 使用 DOM 进行控制 一.HTML5 <video> 元素同样拥有方法.属性和事件. 其中的方法用于播放.暂停以及加载等.其中的属性(比如时长.音 ...
- Node.js Express 路由文件分类
前言 基于上一篇Web Api Controller分类,在MVC中我们通常要按自己的业务来划分Controller层, 好处多多,那么Express框架作为Node.js的一款MVC框架,那么自然也 ...
- HTML基本元素(一)
HTML基本元素(一) 1.换行符 <br /> Ps:br 是换行(Break)的缩写,文本会在这个标签的地方换行. 实例: 第一行<br />第二行 2.段落 <p& ...
- 原来css中的border还可以这样玩
原来css中的border还可以这样玩 前面的话: 在看这篇文章之前你可能会觉得border只是简单的绘制边框,看了这篇文章,我相信你也会跟我一样说一句"我靠,原来css中的border还可 ...
- 通过 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(二)
我们上一篇<基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)>主要讲解了如何搭建一个实时数据通讯服务器,客户端与服务端是如何通讯的,相信通过上一篇的讲解,再配 ...