## 模板方法模式的简单介绍
模板方法模式是行为型模式的一种,用来定义一个操作中的算法骨架。
如何去理解算法骨架呢?也就是说我们在设计这个算法的时候,就清晰的知道了算法所需要的关键步骤,而且确定了这些步骤的执行顺序,但是某些具体的步骤无法确定,或者是具体的步骤需要根据场景做调整。
模板方法其实更强调于因地制宜,同样的一个方法,不同场景得到的结果是不一样的。
用最简单的语言描述,就是通过模板方法去调用一系列的子方法,子方法可以定义为抽象方法,可以交给不同的子类去实现,从而实现高度的可扩展性。
模板方法模式的类图:
模板方法模式的具体实现思路
- 通过抽象类定义共性的方法,特性的方法通过抽象方法表示,定义模板方法(算法骨架)。
- 通过不同的子类实现差异化。
- 模板方法中可以通过钩子函数增加灵活性。
模板方法模式的具体实现方案
// 抽象类
public abstract class AbstractTemplate {
// 模板方法
// 为防止恶意操作,一般情况下模板方法都加上final关键词。
public final void templateMethod() {
// 这几个方法的调用及顺序构成算法骨架
// 抽象方法(特异性方法)
abstractMethod1();
// 钩子函数
HookMethod1();
if (HookMethod2()) {
// 公共方法
SpecificMethod();
}
// 抽象方法
abstractMethod2();
}
// 具体方法,将共性的实现交由抽象类实现
public void specificMethod() {
// 具体逻辑
}
// 钩子方法也可以在抽象类中实现,然后通过子类改写
// 钩子方法1
public void HookMethod1() {
}
// 钩子方法2
public boolean HookMethod2() {
return true;
}
// 抽象方法1
public abstract void abstractMethod1();
// 抽象方法2
public abstract void abstractMethod2();
}
// 具体实现类
public class ConcreteTemplate extends AbstractTemplate {
@Override
public void abstractMethod1() {
// 具体实现
}
@Override
public void abstractMethod2() {
// 具体实现
}
// 方法重写
@Override
public void hookMethod1() {
// 具体实现
}
// 方法重写
@Override
public boolean hookMethod2() {
return false;
}
}
模板方法模式的优缺点
优点
- 封装了不变部分,扩展可变部分。
- 提取了公共的部分代码,便于代码复用。
- 通过增加子类可以很好的扩展算法,符合开闭原则。
缺点
- 对于不同的实现都需要增加一个子类,这会导致系统的类增多
- 模板方法模式设计更加抽象,增加了系统实现的复杂度。
- 通过子类方法影响父类方法,这导致一种反向的控制结构,它提高了代码阅读的难度。
- 基于继承关系自身的特点,父类添加新的抽象方法,所有子类都需要同步修改一遍。
模板方法模式的适用场景
- 算法的整体步骤很固定,但是其中一些方法需要根据场景不同,进行不同的实现,我们就可以将易变的抽象出来,交由子类实现。
- 当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。
- 当需要控制子类的扩展部分是否执行时,可以在特定的方法前调用钩子操作,这样就增强了模板方法的灵活性。
模板方法模式总结
模板方法模式注重解决的问题是复杂算法,固定算法套路,场景不同实现不同。遇到这三个特点的场景,我们就可以考虑使用模板方法去实现或者是优化重构。
Spring中的AbstractApplicationContext中的refresh()就是模板方法模式。