- 模版方法模式的抽象父类有两类方法:具体方法、模版方法
- 将具体处理(干活的)的实现交给子类,父类只是定义方法体,子类负责具体处理(干活的)实现;而将处理框架、规则、顺序、流水、各类异常情况判断 交给父类的“模版方法”。
- 特点:
- 在模版方法模式中,父类、子类是紧密联系、共同工作的。因此,在子类中实现父类中声明的方法,必须要理解这些抽象方法被调用的时机。在看不到父类源代码的情况下,想要编写出子类是非常困难的。
- 一般模板方法都加上final关键字,不允许被覆写。
- 优点:
- 在父类的模版方法中编写了算法,而无需在每个子类中再编写算法。
- 把算法中认为是不变部分的算法封装到父类实现,而可变部分的则可以通过继承来继续扩展
- 缺点:
- 按照我们设计习惯,抽象类负责声明最抽象、最一般的事物属性和方法,实现类完成具体的事物属性和方法,但是模板方法模式却颠倒了,抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响,这在复杂的项目中,会带来代码阅读的难度,而且也会让新手产生不适感。
- 使用场景
- 多个子类有公有的方法,并且逻辑基本相同时。
- 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
- 如何扩展:
- 模版方法一般设计为final,不能在子类中多态;为了确保模版方法本身的灵活性,可以在模版方法本身中设置多个判断条件(可以是变量、可以是方法,切可在子类中重构)。判断条件的运行时情况,依据子类的多态重写情况而定。
- 类图
- 代码结构
模板方法在一些开源框架中应用非常很多,基础系统提供了一个抽象类,然后开源框架写了一堆子类,如果你需要扩展功能,可以继承了这个抽象类,然后覆写protected方法,再然后就是调用一个类似execute方法,就完成你的扩展开发,非常容易扩展的一种模式。
public abstract class AbstractClass { // 基本方法 protected abstract void doSomething(); // 基本方法 protected abstract void doAnything(); // 模板方法 public void templateMethod() { /* * 调用基本方法,完成相关的逻辑 */ this.doAnything(); this.doSomething(); } }
public class ConcreteClass1 extends AbstractClass { // 实现基本方法 protected void doAnything() { // 业务逻辑处理 } protected void doSomething() { // 业务逻辑处理 } }