22.设计模式-TEMPLATE METHOD(模板方法)

一、模式定义与核心思想

模板方法模式是一种行为型设计模式,其核心目标是定义算法的骨架,将某些步骤延迟到子类中实现。该模式通过将不变逻辑与可变逻辑解耦,实现以下核心价值:

  1. 算法复用:在抽象类中固化公共流程,减少重复代码(如Spring框架的JdbcTemplate统一处理数据库连接)。
  2. 扩展可控:子类仅重写特定步骤,避免破坏整体结构(如游戏角色状态机中不同行为的差异化实现)。
  3. 反向控制:父类控制流程调用顺序,子类专注具体实现(如Android Activity生命周期管理)。

核心设计哲学

  • 封装不变:公共步骤(如资源初始化、异常处理)在抽象类中实现,消除冗余。
  • 开放变化:通过抽象方法或钩子方法(Hook Method)暴露扩展点,支持灵活定制。

典型应用场景

  • 框架设计(如Spring Boot自动配置流程)
  • 多平台功能适配(如跨系统安装器统一流程)
  • 业务流程标准化(如电商订单状态流转)

二、模式组成与UML类图

核心角色
  1. AbstractClass(抽象类)
    • 定义模板方法templateMethod(),编排算法步骤(如prepareRecipe()定义饮料制作流程)。
    • 包含具体方法(如boilWater())和抽象方法(如brew())。
  1. ConcreteClass(具体类)
    • 实现抽象方法,提供差异化逻辑(如CoffeeTea重写冲泡步骤)。
    • 可选覆盖钩子方法实现流程微调(如跳过某些步骤)。
UML类图
classDiagram
    class AbstractClass {
        <<abstract>>
        +templateMethod()
        #step1()
        #step2()
        +concreteStep()
    }

    class ConcreteClassA {
        +step1()
        +step2()
    }

    class ConcreteClassB {
        +step1()
        +step2()
    }

    AbstractClass <|-- ConcreteClassA
    AbstractClass <|-- ConcreteClassB


三、代码实现示例

场景:实现跨平台文件处理框架(文本文件与二进制文件差异化解析)

1. 抽象类定义模板方法
public abstract class FileProcessor {
    // 模板方法(final防止子类重写流程)
    public final void processFile(String filename) {
        openFile(filename);
        readData();
        closeFile();
    }

    // 抽象方法(由子类实现)
    protected abstract void openFile(String filename);
    protected abstract void readData();

    // 具体方法(公共逻辑)
    private void closeFile() {
        System.out.println("关闭文件句柄");
    }
}
2. 具体类实现差异化逻辑
// 文本文件处理器
public class TextFileProcessor extends FileProcessor {
    @Override
    protected void openFile(String filename) {
        System.out.println("以文本模式打开文件: " + filename);
    }

    @Override
    protected void readData() {
        System.out.println("逐行读取文本内容...");
    }
}

// 二进制文件处理器
public class BinaryFileProcessor extends FileProcessor {
    @Override
    protected void openFile(String filename) {
        System.out.println("以二进制模式打开文件: " + filename);
    }

    @Override
    protected void readData() {
        System.out.println("按字节流读取二进制数据...");
    }
}
3. 客户端调用
public class Client {
    public static void main(String[] args) {
        FileProcessor textProcessor = new TextFileProcessor();
        textProcessor.processFile("demo.txt");

        FileProcessor binaryProcessor = new BinaryFileProcessor();
        binaryProcessor.processFile("data.bin");
    }
}

四、工业级源码应用

  1. Spring框架的JdbcTemplate
    • JdbcTemplate.execute()方法定义SQL执行流程(获取连接、创建语句、执行、释放资源),具体SQL逻辑由回调接口实现。
public class JdbcTemplate {
    public <T> T execute(ConnectionCallback<T> action) {
        Connection con = getConnection();
        try {
            return action.doInConnection(con);
        } finally {
            releaseConnection(con);
        }
    }
}
  1. Android Activity生命周期
    • Activity.onCreate()/onPause()等方法为模板方法,子类重写特定生命周期回调。
  1. Java AQS同步器
    • AbstractQueuedSynchronizer定义获取锁的模板方法acquire(),子类实现tryAcquire()等抽象方法。
  1. Spring Boot自动配置
    • @EnableAutoConfiguration通过AutoConfigurationImportSelector加载配置类,模板方法模式筛选符合条件的配置。
  1. 游戏引擎状态机
    • Unity的角色行为状态机使用模板方法定义Enter()/Update()/Exit()流程,子类实现具体状态逻辑。

五、模式优劣与最佳实践

优势

  • 代码复用率提升30%+:公共流程集中维护(如JDBC资源管理)。
  • 符合开闭原则:新增功能通过扩展而非修改实现(如新增文件处理器类型)。

局限性

  • 类膨胀风险:每个差异化实现需单独子类(可通过组合模式优化)。
  • 继承强耦合:子类与父类绑定,影响单元测试(推荐结合依赖注入)。

最佳实践

  1. 钩子方法扩展:在模板方法中插入空方法(如beforeRead()),允许子类选择性覆盖。
  2. 与策略模式结合:将可变步骤委托给策略接口,减少子类数量。
  3. 异步流程支持:模板方法中集成CompletableFuture实现非阻塞调用(如高并发文件处理)。

总结

模板方法模式如同软件架构的“标准化流水线”,通过流程固化局部定制的巧妙平衡,在框架设计、跨平台适配等领域展现出强大的生命力。其设计精髓在于将稳定性灵活性统一,开发者需重点把控抽象方法的粒度,结合具体场景选择继承或组合策略,从而构建出高复用、易维护的现代化系统架构。

posted @ 2025-04-12 10:59  雾里看花的少年  阅读(36)  评论(0)    收藏  举报