JS设计模式--模板方法模式

本文深入探讨了设计模式中的模板方法模式,介绍了其基本概念、优点、缺点及应用场景。通过具体的面试流程示例,展示了如何使用模板方法模式实现算法框架的封装,以及子类如何通过重写方法来扩展功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计模式–模板方法模式

什么是模板方法模式

它是一种只需使用继承就可以实现的模式,由两部分结构组成,第一部分为抽象父类,第二部分为具体的实现子类,通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序。子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。这可以确保算法的结构保持不变,同时由子类提供部分实现。

优缺点:

优:封装不变部分,扩展可变部分,把认为不变部分的算法封装到父类中去实现,而可变部分的就可以通过继承来继续扩展。
可以复用公共方法,子类也不需要实现算法部分。
行为由父类控制,子类实现。
缺:按照设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,而实现类负责完成具体的事务属性和方法,但是模板方式正好相反,子类执行的结果影响了父类的结果,会增加代码阅读的难度。

使用场景

一般用于可以抽取公共方法,比如泡咖啡,泡红茶,或者各个企业的面试流程等例子;

例子

比如BAT面试过程:笔试、技术面、HR面、等通知
在这里首先要定义一个BAT面试的构造函数

var TxInterview=function() {};

下面就把面试的流程封装成它的方法
1、笔试

TxInterview.prototype.written=function(){
console.log("一堆笔试题")}

2、技术面

TxInterview.prototype.FEInterview=function(){
console.log('开始你的表演')
}

3、HR面

TxInterview.prototype.HRInterview=function(){
console.log('又一轮表演')
}

4、等通知

TxInterview.prototype.tellIMe=function(){
console.log('盯着手机看来电显示')
}

综合上面,一个代码结构就出来了,下面给他初始化一个方法:

TxInterview.prototype.init=function(){
this.written();
this.FEInterview();
this.HRInterview();
this.tellIMe();
}

然后去实现它

var TxInterview=new TxInterview();
TxInterview.init();

基本上面试的基本流程和上面的代码差不多,大部分的公司面试流程跟这个相似,只不过步骤的内容不一样而已。由此可以把流程抽象出来,下面,可以改变一下前面的代码


1var Interview=function(){}  //面试
2、
TxInterview.prototype.written=function(){
console.log("一堆笔试题")}
TxInterview.prototype.FEInterview=function(){
console.log('开始你的表演')
}
TxInterview.prototype.HRInterview=function(){
console.log('又一轮表演')
}
TxInterview.prototype.tellIMe=function(){
console.log('盯着手机看来电显示')
}
TxInterview.prototype.init=function(){
this.written();
this.FEInterview();
this.HRInterview();
this.tellIMe();
}
3var TxInterview=function(){}
TxInterview.prototype=new Interview();

由此能看出,不管是去哪个公司面试,只有最后一步才可以复用,所以我们需重写子类不能复用的方法

TxInterview.prototype.written=function(){
console.log("一堆笔试题")}
TxInterview.prototype.FEInterview=function(){
console.log('开始你的表演')
}
TxInterview.prototype.HRInterview=function(){
console.log('又一轮表演')
}

接下来实例化子类的对象

var TxInterview=new TxInterview();
TxInterview.init();

抽象出来的模板类和子类完成了, 这里直接调用TxInterview.init()方法,Txinterview本身并没有init()方法,但是它继承了父类,会迎着原型链到父类中去查找。
如果还想继承其他子类,好比面试类的代码是一样的。Interview.prototype.init()是模板方法,它封装了子类中算法框架,而它作为一个算法的模板,去指导子类以什么样的顺序去执行代码。

以上是类式写法,在JS中,可以写的更容易懂。


创建Interview函数

var Interview=function(param){
var written=param.written||function(){
throw new Error('必须传written方法')}var FEInterview=param.FEInterview||function(){
throw new ERROW('必须传FEInterview方法')},
var HRInterview=param.HRInterview||function(){
throw new ERROW('必须传HRInterview方法')},
var tellMe=function(){
console.log('盯着手机看来电显示');
}
var A=function(){};
A.prototype.init=function(){
written();
FEInterview();
HRInterview();
tellMe();
}
return A;
}

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

var TxInterview=Interview({
written:function(){
console.log('一堆笔试题');
},
FEInterview:function(){
console.log('开始你的表演')
},
HRInterview:function(){
console.log('又一轮表演');
}
})

最后一步去完成TxInterview

var TxInterview=new TxInterview();
TxInterview.init();

以上代码明白了一种新的设计原则–好莱坞原则:“别调用我们,我们会调用你”这一反向控制结构,子类放弃了对自己的控制权,而是改为父类通知子类,作为子类,只负责提供一些设计上的细节,指定算法骨架,让子类具体实现,这大概就是模板方法模式。

好莱坞原则

我们允许底层组件将自己挂钩到系统上,但是高层组件可以决定什么时候和如何使用这些底层组件,换句话说就是别调用我们,我们会调用你。而该原则会教我们一个技巧,创建一个有弹性的设计,允许底层结构能够互相操作, 而又防止其它类太过依赖它们。而好莱坞的目标也是在于解耦。所以它会将决策权放在高层模块中,以便决定如何以及何时调用底层模块。

实现钩子

对模板方法进行挂钩,狗子是一种被声明在抽象类中的方法,它在抽象类中不做事,或者只做默认的事情,钩子的存在,可以让子类有能力对算法的不同点进行挂钩,在你写模板方法的时候,算法内的步骤不要太少,否则会没弹性,而且也是要看情况而定的,如果某些步骤是可选的,那么你可以将这些步骤是线程钩子,而不是实现成抽象方法。同时可以让抽象类的子类的负荷减轻。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值