模板模式:定义一个算法的框架,将一些方法由子类实现。简单说,就是为子类设计一套执行流程,以便子类可以复用这套流程。
模板模式由抽象父类和子类构成,父类中包含:
- 模板方法(定义执行流程,子类调用)
- 抽象方法(子类必须实现)
- 钩子方法(微调模板方法的执行流程,子类可选择重写或不重写)
- 具体方法(子类不可重写)
下面以学生考试为例,具体介绍模板模式:
定义抽象父类:
public abstract class Exam {
public void answerOrder() {
choiceQuestion();
shortAnswerQuestion();
if (doAdditionalQuestions()) {
additionalQuestions();
}
commitPaper();
}
private void choiceQuestion() {
System.out.println("先做选择题");
}
private void shortAnswerQuestion() {
System.out.println("再做简答题");
}
private void additionalQuestions() {
System.out.println("最后做附加题");
}
protected boolean doAdditionalQuestions() {
return true;
}
abstract void commitPaper();
}
定义子类:
public class MyExam extends Exam {
private boolean doAdditional;
public MyExam(boolean doAdditional) {
this.doAdditional = doAdditional;
}
@Override
void commitPaper() {
System.out.println("提前交卷");
}
@Override
protected boolean doAdditionalQuestions() {
return doAdditional;
}
}
定义业务类:
public class Test {
public static void main(String[] args) {
Exam myexam = new MyExam(false);
myexam.answerOrder();
}
}
先做选择题
再做简答题
提前交卷
我们都知道,考试中我们都有固定的答题顺序,一般是先做选择,再做简答,附加题可做可不做,最后我们决定准时交卷还是提前交卷。所以在父类的模板方法中,我们定义了一系列的执行流程,并提供钩子方法让子类重写来决定是否做附加题,还提供了抽象方法让子类实现必须交卷的方法。
模板模式的要点在于复用抽象类的公共方法,重写抽象类中的抽象方法,选择性使用抽象类的钩子方法。
总结一句话:子类可以重写父类中允许改变的逻辑。
模板模式可以提高代码的扩展性,父类控制流程,子类实现具体流程,符合开闭原则。