一、简介
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。即对于具有多个步骤的算法,在抽象类中先定义好执行步骤,然后将某些步骤的实现交给子类去实现,实现了模板的作用。
拿学生做作业来说,有如下三个步骤:
- 领取作业
- 完成作业
- 提交作业
对于步骤1和3来说,是不需要学生参与的,而步骤2则需要每个学生去具体实现。
二、实例
抽象学生类:
/**
* 抽象学生类
*/
public abstract class Student {
/**
* 定义成final防止子类继承
*/
public final void doHomework() {
receive();
complete();
submit();
}
/**
* 领取作业
*/
private void receive() {
System.out.println("老师布置作业啦!");
}
/**
* 完成作业,具体由学生子类实现
*/
abstract void complete();
/**
* 提交作业
*/
private void submit() {
System.out.println("终于做完了,提交作业啦!");
}
}
具体学生类:
public class StudentImpl extends Student {
@Override
void complete() {
System.out.println("我正在努力做作业!");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Student student = new StudentImpl();
student.doHomework();
}
}
抽象父类中默认调用了三个步骤,对于其中的一个或多个步骤的实现,交由子类处理,相当于提供了一个方法模板,由子类去定义某些具体细节,这就是模板方法模式的核心思想。
三、抽象方法的钩子(Hook):
如果子类不需要执行某个步骤,可以在抽象类中提供一个钩子,这个钩子相当于开关的作用。以上面的例子来说,有些作业是不需要提交的。
父类代码如下:
/**
* 抽象学生类
*/
public abstract class Student {
/**
* 定义成final防止子类继承
*/
public final void doHomework() {
receive();
complete();
//此处加了一个判断
if (isNeedToSubmit()) {
submit();
}
}
/**
* 领取作业
*/
private void receive() {
System.out.println("老师布置作业啦!");
}
/**
* 完成作业,具体由学生子类实现
*/
abstract void complete();
/**
* 提交作业
*/
private void submit() {
System.out.println("终于做完了,提交作业啦!");
}
/**
* 由子类去实现是否需要提交
*/
protected abstract boolean isNeedToSubmit();
}
实现类:
public class StudentImpl extends Student {
@Override
void complete() {
System.out.println("我正在努力做作业!");
}
@Override
protected boolean isNeedToSubmit() {
return false;
}
}