前言
- 掌握模板方法模式的原理
- 掌握模板方法模式的应用场景
- 掌握模板方法的优缺点
一、定义
模板方法模式(Template Method):定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
实际上是封装了一个固定流程,该流程由几个步骤组成,具体步骤可以由子类进行不同实现,从而让固定的流程产生不同的结果。
二、应用场景
- 一次性实现一个算法不变的部分,并将可变的行为留给子类来实现
- 各子类中公共的行为被提取出来并几种到一个公共的父类中,从而避免代码重复
- 当需要控制子类扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展
三、基本结构
- 抽象类/抽象模板角色(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干基本方法构成。
- 具体子类/具体实现角色(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,他们是一个顶级逻辑的一个组成步骤。
- 客户端角色(Client):调用具体子类/具体实现角色。
模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
基本方法:是整个算法中的一个步骤,包含以下几种类型
- 抽象方法:在抽象类中声明,由具体子类实现。
- 具体方法:在抽象类中已经实现,在具体类中可以继承或重写。
- 钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。
四、基本使用
1. 抽象类/抽象模板角色
public abstract class AbstractClass {
// 模板方法
public void TemplateMethod() {
SpecificMethod();
if (hookMethod()) {
abstractMethod();
}
}
// 具体方法
public void SpecificMethod() {
System.out.println("抽象类中的具体方法被调用...");
}
// 钩子方法
public boolean hookMethod() {
return false;
}
// 抽象方法
public abstract void abstractMethod();
}
2. 具体子类/具体实现角色
public class ConcreteClass extends AbstractClass {
@Override
public boolean hookMethod() {
return true;
}
public void abstractMethod() {
System.out.println("抽象方法的实现被调用...");
}
}
3. 客户端角色
public class Client {
public static void main(String[] args) {
AbstractClass ac = new ConcreteClass();
ac.TemplateMethod();
}
}
总结
1. 优点
- 利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。
- 不同的代码在不同子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。
- 把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则。
2. 缺点
- 类的个数增加,系统更加庞大,设计也更加抽象,间接地增加了系统实现的复杂度。
- 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
- 由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。