## 1 概述

定义一个操作中的算法骨架，而将算法的一些步骤延迟到子类中，使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

模板方法（Template Method）模式包含以下主要角色：

- 抽象类（Abstract Class）：负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。

  - 模板方法：定义了算法的骨架，按某种顺序调用其包含的基本方法。

  - 基本方法：是实现算法各个步骤的方法，是模板方法的组成部分。基本方法又可以分为三种：

    - 抽象方法(Abstract Method) ：一个抽象方法由抽象类声明、由其具体子类实现。

    - 具体方法(Concrete Method) ：一个具体方法由一个抽象类或具体类声明并实现，其子类可以进行覆盖也可以直接继承。

    - 钩子方法(Hook Method) ：在抽象类中已经实现，包括用于判断的逻辑方法和需要子类重写的空方法两种。

      一般钩子方法是用于判断的逻辑方法，这类方法名一般为 isXxx，返回值类型为boolean类型。

- 具体子类（Concrete Class）：实现抽象类中所定义的抽象方法和钩子方法，它们是一个顶级逻辑的组成步骤。

## 2 例子

打游戏有一般先初始化游戏、开始游戏、结束游戏。

```java
public abstract class Game {
    public abstract void initialize();

    public abstract void startPlay();

    public abstract void endPlay();

    //模板
    public final void play() {
        //初始化游戏
        initialize();
        //开始游戏
        startPlay();
        //结束游戏
        endPlay();
    }
}

public class Honor extends Game {
 
   @Override
   void endPlay() {
      System.out.println("王者荣耀结束");
   }
 
   @Override
   void initialize() {
      System.out.println("王者荣耀初始化");
   }
 
   @Override
   void startPlay() {
      System.out.println("王者荣耀开始");
   }
}

public class TestClient {
    public static void main(String[] args) {
        final Honor honor = new Honor();
        honor.play();
    }
}
```

## 3 优缺点

优点

- 提高代码复用性

  将相同部分的代码放在抽象的父类中，而将不同的代码放入不同的子类中。

- 实现了反向控制

  通过一个父类调用其子类的操作，通过对子类的具体实现扩展不同的行为，实现了反向控制 ，并符合“开闭原则”。

缺点

- 对每个不同的实现都需要定义一个子类，这会导致类的个数增加，系统更加庞大，设计也更加抽象。
- 父类中的抽象方法由子类实现，子类执行的结果会影响父类的结果，这导致一种反向的控制结构，它提高了代码阅读的难度。