介绍
模板方法模式属于行为型模式
中一种。因为其规定了一套公共的流程
,其他的都要按照这套模板来进行相关的操作。在我们生活中都存在许多模板方法
;例如,填写的表格、从小到大写的试卷、把冰箱装进大象…等等一系列,已经将完成某件事
的距离模板流程告诉给了你,你只需要根据不同实际的情况来覆盖某些方法
即可。
代码
我们来看一下模板的代码:
// 这里演示一个考试的流程
// 规定好的模板方法
public abstract class F {
// 规定好了考试流程
public void startTest() {
faJuanzi();
writeJuanzi();
if(isWantToZuoBi()){
zuoBi();
}
shouJuanzi();
}
// 因为这一步是考试必定会的,直接拿出来到父类,并且不让子类修改
public final void faJuanzi(){
System.out.println("老师发试卷");
}
// 每个人写卷子过程不一样,交给子类自己去实现
public abstract void writeJuanzi();
// 考试有些人可能会作弊,先加上
public abstract void zuoBi();
public boolean isWantToZuoBi(){
return false;
}
// 最后老师收试卷
public final void shouJuanzi(){
System.out.println("老师收试卷");
}
}
我们再来写其中一个子类的代码:
public class S extends F {
// 规定好了考试流程
public void startTest() {
faJuanzi();
writeJuanzi();
if(isWantToZuoBi()){
zuoBi();
}
shouJuanzi();
}
// 每个人写卷子过程不一样,交给子类自己去实现
public void writeJuanzi(){
System.out.println("我先写大题!");
System.out.println("我然后写选择题!");
}
// 我不作弊我不实现他
public void zuoBi(){
}
}
我们再来看另外一个子类的代码:
public class S1 extends F {
// 规定好了考试流程
public void startTest() {
faJuanzi();
writeJuanzi();
if(isWantToZuoBi()){
zuoBi();
}
shouJuanzi();
}
// 每个人写卷子过程不一样,交给子类自己去实现
public void writeJuanzi(){
System.out.println("我啥都不写!");
}
// 我作弊
public void zuoBi(){
System.out.println("我掏出了手机查答案!");
}
// 我想作弊,重写了父类的isWantToZuoBi()方法
public boolean isWantToZuoBi(){
return true;
}
}
Main方法:
public class Main {
public static void main(String[] args) {
F f = new S();
f.startTest();
System.out.println("============================");
F f1 = new S1();
f1.startTest();
}
}
程序执行结果:
简单分析
-
首先我们看到父类使用了
final
关键字,让方法不可变。当我们不允许子类修改的时候
,可以给对应的方法加上这个关键字,子类就无权进行修改。 -
其次,我们看到有
abstract
方法,这个就是让子类自己去实现
;尽管总体的流程已经给出,但是个体的差异还是存在的,不同的子类有自己不同的步骤点
。所以,在模板方法中会预留抽象方法
给子类自己去实现。 -
然后,我们看到了一个作弊方法。并且在
startTest()
方法中用了一个条件来判断是否执行,这个就是模板方法中的钩子函数。模板只能规定大众通用
的方式,但是对于极少数特别的方法
,我们需要特别处理,并且这些方法别的子类不一定需要
,所以使用了钩子函数进行选择。父类可以给定默认值(一般给定大众默认那个)
,如果子类这个方法,那么重写默认值,打开权限
,这样在执行的时候就可以进入这个方法。
应用场景
模板方法在很多场景都有使用,比如JUC中的AQS就运用了模板方法、以及Spring中的各种temple、还有在mybatis中的execute中,将doUpdate()
放出来让不同的执行器去实现他…等等这些都运用了模板方法,具体的案例还有很多就不一一列举了。
小结
模板方法模式规定了一套模板流程
,在一定程度上可以减少了代码的冗余和出错
,但是也要在适当的地方中运用,不要为了优化而优化。