1 定义
模板方法模式定义了一个算法的步骤,并允许子类为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。
《百度百科》
模板方法模式,首先从名字看,关键点就是模板,模板很好理解,就是定义好一个模板,然后其他需要用到这个模板的地方根据定义好的模板做自己的实现。
例如HR发给你一个转正答辩的PPT模板,在PPT模板中已经划分好了工作总结、下阶段职业规划等大纲,且规定必须按照这个大纲来做PPT,那么这个PPT就是模板,而每个人在不改变大纲的情况下去写不同的内容,这个就是子类为一个或多个步骤提供其实践方式。
2 示例
2.1 类图
PPT做为模板类,在该模板类中有demonstration()、workSummary()和nextPlanning()三个方法,其中demonstration()为模板方法,模板方法在模板类中默认实现且不可被继承,其中定义了模板的行为,例如在本例的模板方法中规定了workSummary()和nextPlanning()的执行顺序,和其他相同的操作。workSummary()和nextPlanning()则是需要子类自己实现的抽象方法。
2.2 代码实现:
首先先定义出PPT模板和模板方法
public abstract class PPT {
// PPT演示
public final void demonstration(){
System.out.println("开始演示"); // 相同的前置操作
// 模板的流程,先执行workSummary再执行nextPlanning
workSummary();
nextPlanning();
System.out.println("演示结束"); // 相同的后置操作
}
// 工作总结
public abstract void workSummary();
// 下阶段工作规划
public abstract void nextPlanning();
}
其中定义出的PPT模板类使用abstract修饰为抽象类,并且类中的模板方法demonstration()使用final修饰,这样做的目的是防止子类的恶意修改。而需要子类具体实现的方法则使用abstract修饰,这样做的目的是强制子类必须实现。
然后根据PPT模板实现不同的子类:
子类Person1
public class Person1PPT extends PPT{
@Override
public void workSummary() {
System.out.println("Person1的总结");
}
@Override
public void nextPlanning() {
System.out.println("Person1的规划");
}
}
子类Person2
public class Person2PPT extends PPT{
@Override
public void workSummary() {
System.out.println("Person2的总结");
}
@Override
public void nextPlanning() {
System.out.println("Person2的规划");
}
}
上述可见,Person1和Person2都继承了模板类PPT,并且都实现了父类的workSummary()和nextPlanning()两个方法。
测试方法:
public class Main {
public static void main(String[] args) {
PPT person1 = new Person1PPT();
PPT person2 = new Person2PPT();
person1.demonstration();
person2.demonstration();
}
}
运行结果:
3 总结
优点:
- 模板类中封装了不变部分,可变的部分由子类扩展。
- 公共代码提取在父类中,便于代码复用。
- 行为由父类控制,具体的实现由子类完成。
缺点:
- 每一个不同的实现都需要一个子类,会导致类的数量增加。
- 模板方法中的步骤越多, 维护工作就会越困难。
使用场景:
- 当多个类的逻辑和步骤一致,且只有其中部分内容有区别,则可采用模板方法模式。
使用步骤:
- 将相同的部分提取到父类的模板方法中。
- 在父类的模板方法中确定逻辑和流程。
- 将不同的部分抽象成抽象方法,由不同的子类实现。