模板方法模式:

把相似的流程抽象出来作为一个父类,来封装好子类的算法框架,然后子类继承这个父类,并且可以重写非公有的方法,来实现自己的业务逻辑。


聚个栗子

泡茶泡咖啡是很好的例子,不同企业的面试流程也是一个很好的例子
对于很多大型公司,比如BATTMD ,面试过程类似,先来简单假设一下面试过程:

  • 笔试
  • 技术面试
  • HR面试
  • 等通知

那么假如不久的将来我就要去面试了,拿即将上市的小米来举个例子(小白也有一个大厂梦啊),在JavaScript代码中意淫一下小米的面试流程

首先,定义一个小米面试的构造函数

var XiaomiInterview = function () {}

接下来,把面试的流程封装成它的方法

1.笔试

XiaomiInterview.prototype.writtenTest=function(){console.log("看到小米的笔试题,紧张,激动~");
}

2.技术面

XiaomiInterview.prototype.technicalInterview=function(){console.log("我是小米的前端技术负责人......");
}

3.HR面

XiaomiInterview.prototype.HRInterview = function (){console.log("小米的HR小姐姐来面试我了,扑腾扑腾~");
}

4.等通知

XiaomiInterview.prototype.waitNotice=function(){console.log("等得花儿都谢了,是不是凉凉了~");
}

现在代码的基本结构已经有了,再来为它初始化一个方法

XiaomiInterview.prototype.init=function(){this.writtenTest();this.technicalInterview();this.HRInterview();this.waitNotice();
}

实现它

var xiaomiInterview = new XiaomiInterview();
xiaomiInterview.init();

小米面试的基本流程如上面的代码,不管是BATTMD面试流程应该都跟这个类似,只是步骤的内容不一样,就不一一枚举了

那么不妨把流程抽象出来

接下来,就来改写一下前面的代码

首先定义一个类,就叫Interview

var Interview = function () {}            //面试类

再抽象出方法

Interview.prototype.writtenTest=function(){console.log("终于看到XX的笔试题了~");
}
Interview.prototype.technicalInterview=function(){console.log("你好,我是XX的前端技术负责人");
}
Interview.prototype.HRInterview=function(){console.log("XXHR来面试我了");
}
Interview.prototype.waitNotice=function(){console.log("到现在都不给我通知,是不是凉凉了~");
}
Interview.prototype.init=function(){this.writtenTest();this.technicalInterview();this.HRInterview();this.waitNotice();
}

现在,创建一个XiaomiInterview子类来继承父类的算法框架

var XiaomiInterview = function () {}
XiaomiInterview.prototype = new Interview();

发现不管面哪一家,只有“等通知,凉凉”这一步是可以复用的T.T,所以我们需要重写子类不能复用的方法

XiaomiInterview.prototype.writtenTest=function(){console.log("看到小米的笔试题,紧张,激动~");
}
XiaomiInterview.prototype.technicalInterview=function(){console.log("我是小米的前端技术负责人......");
}
XiaomiInterview.prototype.HRInterview=function(){console.log("小米的HR小姐姐来面试我了,扑腾扑腾~");
}

现在来实例化子类的对像

var xiaomiInterview = new XiaomiInterview();
xiaomiInterview.init();

抽象出来的模板类和子类已经完成了,这里直接调用xiaomiInterview.init()方法,xiaomiInterview本身并没有init()方法,但是它继承了父类,会迎着原型链到父类中查找。

如果还想继承其他子类,比如BAT面试类代码也是一样的。Interview.prototype.init() 是模板方法,他封装了子类中算法框架,它作为一个算法的模板,去指导子类以什么样的顺序去执行代码。


回顾一下刚才的代码,这是类式写法,在JavaScript中,可以写的更佳优雅

接下来,用js风格来表示上述的模板方法模式

创建Interview函数对象作为模板方法,它能接受一个JSON对象(传入子类需要重写的方法),创建一个F函数并给F函数添加init方法调用模板中的流程,最后返回F

var Interview = function (param) {var writtenTest = param.writtenTest || function() {throw new Error('必须传writtenTest方法');}var technicalInterview = param.technicalInterview || function() {throw new Error('必须传technicalInterview方法');}var HRInterview = param.HRInterview || function() {throw new Error('必须传HRInterview方法');}var waitNotice = function() {console.log("到现在都不给我通知,是不是凉凉了~");}var F = function () {}F.prototype.init = function () {writtenTest();technicalInterview();HRInterview();waitNotice();}return F;
}

重写XiaomiInterview无法复用的方法并传入到模板方法,来实现继承

var XiaomiInterview = Interview({writtenTest:function(){console.log("看到小米的笔试题,紧张,激动~");},technicalInterview:function(){console.log("我是小米的前端技术负责人......");},HRInterview:function(){console.log("小米的HR小姐姐来面试我了,扑腾扑腾~");}
});

最后一步,完成xiaomiInterview

var xiaomiInterview = new XiaomiInterview();
xiaomiInterview.init();

完整的js风格代码

var Interview = function (param) {var writtenTest = param.writtenTest || function() {throw new Error('必须传writtenTest方法');}var technicalInterview = param.technicalInterview || function() {throw new Error('必须传technicalInterview方法');}var HRInterview = param.HRInterview || function() {throw new Error('必须传HRInterview方法');}var waitNotice = function() {console.log("到现在都不给我通知,是不是凉凉了~");}var F = function () {}F.prototype.init = function () {writtenTest();technicalInterview();HRInterview();waitNotice();}return F;
}
var XiaomiInterview = Interview({writtenTest:function(){console.log("看到小米的笔试题,紧张,激动~");},technicalInterview:function(){console.log("我是小米的前端技术负责人......");},HRInterview:function(){console.log("小米的HR小姐姐来面试我了,扑腾扑腾~");}
});
var xiaomiInterview = new XiaomiInterview();
xiaomiInterview.init();

运行一下,查看结果,顺利完成了所有的流程

通过以上的实验,渐渐明白了,“别找我们,我们找你”这一著名的好莱坞原则描述的反向控制结构。子类放弃了对自己的控制权,而是改为父类通知子类,作为子类,只负责提供一些设计上的细节。制定算法骨架,让子类具体实现,这大概就是模板方法模式了吧

javascript设计模式学习日记--模板方法模式相关推荐

  1. 设计模式学习(八) 模板方法模式

    引入 定义:在一个方法中定义了一个算法的骨架,而将一些一些步骤延迟到子类中.模板方法使得子类可以在不改变算法接口的情况下,重新定义算法中的某些步骤. uml类图 这个模式是用来创建一个算法的模板,什么 ...

  2. Java设计模式学习 - 模版方法模式策略模式

    个人博客项目地址 希望各位帮忙点个star,给我加个小星星✨ 设计模式-模板方法&策略模式 简单介绍 模板方法模式(Template):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中. ...

  3. 设计模式学习之代理模式学习(一)

    设计模式学习之代理模式学习(一) 关于设计模式想必学习过Java语言的人都知道吧,当时对其进行深入学习的的人应该不是很多.在我看来设计方面的知识相比于框架应用配置等知识要有意思的多,并且设计模式的对一 ...

  4. JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

  5. 设计模式 - 学习笔记 - 工厂模式Factory Pattern

    设计模式 - 学习笔记 - 工厂模式Factory Pattern 1. 简单工厂 1.1 应用场景 1.2 UML 1.3 优劣分析 好处 缺点 1.4 代码示例 抽象产品 AbstractProd ...

  6. 咖啡泡JAVA_java《Head First 设计模式》之模板方法模式——冲泡咖啡和茶

    <Head First 设计模式>之模板方法模式--冲泡咖啡和茶 模板方法模式(Template) 在一个方法中定义了一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变 ...

  7. javascript设计模式之装饰器模式(结构型模式)

    javascript设计模式之装饰器模式 js的设计模式分为创建型模式,结构型模式和行为模式 结构模式描述了如何组合对象以提供新的功能. 装饰器模式是一种常见的结构型模式,我们可以以一个基础对象为基础 ...

  8. 再起航,我的学习笔记之JavaScript设计模式23(中介者模式)

    中介者模式 概念介绍 中介者模式(Mediator):通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用降低他们之间的耦合,有时中介者对象也可以改变对象之间的交互. 创建一个中介 中介者模 ...

  9. 学习php开发步骤,学习php设计模式 php实现模板方法模式

    一.意图 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.Template Method 使得子类可以在不改变一个算法的结构的情况下重定义该算法的某些特定的步骤[GOF95] 二.模板方法模式结 ...

最新文章

  1. Linux中shell命令的用法和技巧
  2. jsp cookie 中文乱码 的解决方法
  3. PHP 多维数组转json对象
  4. [css] border-radius:50%和border-radius:100%有什么区别?
  5. maven的仓库、生命周期与插件
  6. 高效实用Kafka-Kafka消息处理(底层原理)
  7. 系统镜像服务器,服务器系统镜像
  8. Echarts数据可视化title标题,开发全解+完美注释
  9. Solr4.8.0源码分析(13)之LuceneCore的索引修复
  10. coreldraw x4忽略视图样式补丁_80%的人都忽略了PPT画布之外的用法,但这6点真的很实用...
  11. 103规约测试软件,Protocoltester(国电南自103规约调试软件)
  12. net.sf.json.JSONArray之fromObject的坑
  13. mysql触发器trigger实例详解
  14. 关于 路标设置 的问题
  15. “深入浅出”学Golang!就选《Head First Go》
  16. ps 图片处理技法 怎样使照片看起来更加清晰
  17. 2016年9月学习总结与反思
  18. 【高频内存与主板内存频率和CPU内存频率之间的关系】
  19. 微信号名称乱码什么情况_微信号改成什么比较好,2020最火微信号!
  20. 一:Debian安装

热门文章

  1. Build gradle : Could not find method packagingOptions() for arguments root Project “fasterDev”
  2. IOS开发笔记14-NSArray的使用
  3. Android之EditText的各种使用
  4. Android 新手常见的10个误区(下)
  5. Java面试题,深入理解final关键字
  6. GeoIP的使用-C语言版
  7. Hadoop mapreduce框架简介
  8. C# 获取电脑的网络连接状态
  9. 【BZOJ】1823: [JSOI2010]满汉全席(2-sat)
  10. 自制奇葩vb面试题,看你能对几道