模板模式
模板模式又叫做模板方法模式(Template Method Pattern),是指定义一个算法骨架,并允许子类为一个或者多个步骤提供实现。模板模式使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤,属于行为型设计模式。
如何把大象放进冰箱?
打开冰箱门–>把大象塞进冰箱–>关闭冰箱门
如何把长颈鹿放进冰箱?
打开冰箱门–>把大象拿出来–>把长颈鹿塞进去–>关闭冰箱门
上面的例子打开冰箱和关闭冰箱是固定的,可以提到抽象类中实现,抽象类的子类只需要实现中间不同的操作就行。
该模式的主要优点如下。
- 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
- 它在父类中提取了公共的部分代码,便于代码复用。
- 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。
该模式的主要缺点如下。
- 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,间接地增加了系统实现的复杂度。
- 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
- 由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。
适用场景
- 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现
- 各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码重复
具体实现
//模板会有一个或多个未实现的方法,而且这几个未实现的方法有固定的执行顺序
public abstract class NetworkCourse {
protected final void createCourse() {
//发布预习资料
this.postPreResource();
//制作课件PPT
this.createPPT();
//在线直播
this.liveVideo();
//提交课堂笔记
this.postNote();
//提交源码
this.postSource();
//布置作业,有些课有作业,有些课没有作业
//如果有作业,检查作业。如果没有作业,流程结束
if (needHomework()) {
cheakHomework();
}
}
abstract void cheakHomework();
//钩子方法,实现课程的微调
protected boolean needHomework() {
return false;
}
final void postSource() {
System.out.println("提交源代码");
}
final void postNote() {
System.out.println("提交课件和笔记");
}
final void liveVideo() {
System.out.println("直播授课");
}
final void createPPT() {
System.out.println("创建备课PPT");
}
final void postPreResource() {
System.out.println("分发预习资料");
}
}
public class JavaCourse extends NetworkCourse{
@Override
void cheakHomework() {
System.out.println("检查Java作业");
}
}
public class BigDataCource extends NetworkCourse{
private boolean needHomeworkFlag = false;
public BigDataCource(boolean needHomeworkFlag) {
// TODO Auto-generated constructor stub
this.needHomeworkFlag = needHomeworkFlag;
}
@Override
protected boolean needHomework() {
// TODO Auto-generated method stub
return this.needHomeworkFlag;
}
@Override
void cheakHomework() {
System.out.println("检查大数据的课后作业");
}
}
public class NetworkCourseTest {
public static void main(String[] args) {
System.out.println("---Java架构师课程----");
NetworkCourse javaCourse = new JavaCourse();
javaCourse.createCourse();
System.out.println("---大数据课程----");
NetworkCourse bigDataCourse = new BigDataCource(true);
bigDataCourse.createCourse();
}
}