目录
模版方法概念
定义:定义了一个算法骨架,并允许子类为一个或多个步骤提供实现。模版方法使得子类在可以在不改变算法结构的情况下,重新定义算法的某些步骤
适用场景:一次性实现一个算法的不变部分,将可变部分留个子类实现;各子类中公共的行为被提取出来并集中到一个公共父类中,从而避免代码的重复编写
优点:提高了复用性;提高了扩展性;符合开闭原则
缺点:类数量增多;增加了系统实现的复杂性;有继承关系的自身缺点,如果父类增加了新的抽象方法,所有子类都要改一遍。
扩展:钩子方法
模版方法使用案例
以讲师制作视频教程为案例,制作过程中一般包含写PPT、制作视频、编写手记等过程。写PPT和制作视频是所有课程必须的,但是写手记是可选的。套用上面👆模版方法的定义,制作视频教程的过程可以抽象为由多个子步骤构成,且需要预留一个钩子方法让子类自己决定是不是需要写手记。
新建抽象父类,父类包含所有步骤
public abstract class ACource {
//制作课程
protected final void makeCource(){
makePPT();
makeVideo();
if(needWriteArtical()){
writeArtical();
}
}
final void makePPT(){
System.out.println("制作PPT");
}
final void makeVideo(){
System.out.println("制作视频");
}
final void writeArtical(){
System.out.println("编写手记");
}
// 钩子方法
protected boolean needWriteArtical(){
return false;
}
abstract void packageCourse();
}
新建设计模式课程类,继承抽象父类。假设设计模式课程都是需要写手记的,此处需要重写父类的钩子函数,返回true
public class DesignPatternCource extends ACource{
@Override
void packageCourse(){
System.out.println("提供课程java源代码 ");
}
@Override
protected boolean needWriteArtical(){
return true;
}
}
再新建前端课程类,相比于设计模式,前端课程需要提供图片素材和前端代码,而且前端课程又有很多细分的课程,例如vue、thymeleafd等,是否需要写手记并不统一,所以需要将是否需要写手记的权利开放给客户端,具体的操作是重写钩子函数,并声明变量控制钩子函数的返回值
public class FECource extends ACource{
private boolean needWriteArticalFlag = false;
@Override
void packageCourse(){
System.out.println("提供课程前端代码 ");
System.out.println("提供课程的图片等素材 ");
}
public FECource(boolean needWriteArticalFlag) {
this.needWriteArticalFlag = needWriteArticalFlag;
}
@Override
protected boolean needWriteArtical(){
return this.needWriteArticalFlag;
}
}
测试如下
public class Test {
public static void main(String[] args) {
System.out.println("开始制作后端课程");
ACource designPatternCource = new DesignPatternCource();
designPatternCource.makeCource();
System.out.println("后端课程结束");
System.out.println();
System.out.println("开始制作前端课程");
ACource fECource = new FECource(true);
fECource.makeCource();
System.out.println("前端课程结束");
}
}
打印输出
模版方法设计模式适用的场景是工作中较常出现的,尤其是钩子方法的合理适用可以规避权限风险,提升代码的可阅读性。
UML类图如下: