模板方法模式

9次阅读

共计 1949 个字符,预计需要花费 5 分钟才能阅读完成。

模板方法模式
定义
定义了一个算法的骨架。并允许子类为一个或多个步骤提供实现。
定义补充
模板方法是的子类可以在不改变算法结构的情况下,重新定义算法的某些步骤
类型
行为型
适用场景

一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码的重复。

优点

提高复用性,将公共代码放在父类中实现提高了复用性
提高拓展性,通过增加子类来拓展新的行为。

缺点
继承关系自身的缺点,如果父类添加新的抽象方法,所有子类都要修改。
下面开始写代码,假设一个场景就是我们要制作一套课程,这些课程可能包含一定包含视频 ppt,不一定包含文章。
public abstract class ACourse {

protected final void makeCourse(){
this.makePPT();
this.makeVideo();
if(needWriteArticle()){
this.writeArticle();
}
this.packageCourse();
}

final void makePPT(){
System.out.println(“ 制作 PPT”);
}
final void makeVideo(){
System.out.println(“ 制作视频 ”);
}
final void writeArticle(){
System.out.println(“ 编写文章 ”);
}
// 钩子方法
protected boolean needWriteArticle(){
return false;
}
abstract void packageCourse();

}
这里定义了一个抽象的课程方法。对于那些一定有的内容我们生命成 final 的,写文章这个方法我们也声明成 final,但是我们定义了一个钩子方法,这个钩子方法子类可以重写,对于需要写文章的方法我们就返回 true,不需要的我们就返回 false。makeCourse 方法中定义了执行流程,在最后我们调用了 this.packageCourse 方法,这个调用其实是在调用子类方法,因为我们这个是交由子类来执行。通过向上转型来调用父类方法,然后 this 指代是当前对象也就是子类对象,不太明白的话等会儿看接下来的代码就知道了。这里判断了钩子函数的结果来决定是否执行写文章这个方法。
public class DesignPatternCourse extends ACourse {
@Override
void packageCourse() {
System.out.println(“ 提供课程 Java 源代码 ”);
}

@Override
protected boolean needWriteArticle() {
return true;
}

}

设计模式课程实现类,这里重写了钩子函数,将其返回值设置成 true。这个提供源代码就算是子类自己的实现。
public class FECourse extends ACourse {
private boolean needWriteArticleFlag = false;
@Override
void packageCourse() {
System.out.println(“ 提供课程的前端代码 ”);
System.out.println(“ 提供课程的图片等多媒体素材 ”);
}

public FECourse(boolean needWriteArticleFlag) {
this.needWriteArticleFlag = needWriteArticleFlag;
}

@Override
protected boolean needWriteArticle() {
return this.needWriteArticleFlag;
}
}

这里是前端课程,因为前端是一个大的区域,前端可以分为 vue,react 等等,所以我们把这个钩子函数也开放出来,只是给一个默认值让应用层自己实现。
public class TemplateMethodTest {
public static void main(String[] args) {
System.out.println(“ 后端设计模式课程 start—“);
ACourse designPatternCourse = new DesignPatternCourse();
designPatternCourse.makeCourse();
System.out.println(“ 后端设计模式课程 end—“);

System.out.println(“ 前端课程 start—“);
ACourse feCourse = new FECourse(false);
feCourse.makeCourse();
System.out.println(“ 前端课程 end—“);

}
}
测试方法,这就讲完了。

正文完
 0