Skip to content

模板方法模式

基础概念

什么是模板方法模式?

答案: 模板方法模式(Template Method Pattern)定义一个操作中的算法骨架,将一些步骤延迟到子类中实现。

使用场景

  • 多个子类有公共方法
  • 算法步骤固定,但某些步骤实现不同
  • 需要控制子类扩展

优点

  • 封装不变部分,扩展可变部分
  • 提取公共代码,便于维护
  • 行为由父类控制,子类实现

缺点

  • 每个不同实现都需要子类
  • 类数量增加

实现方式

基本实现?

答案:

java
// 抽象类
public abstract class AbstractClass {

    // 模板方法
    public final void templateMethod() {
        step1();
        step2();
        step3();
    }

    // 具体方法
    private void step1() {
        System.out.println("步骤1:固定实现");
    }

    // 抽象方法,由子类实现
    protected abstract void step2();

    // 钩子方法,子类可选择性覆盖
    protected void step3() {
        System.out.println("步骤3:默认实现");
    }
}

// 具体类A
public class ConcreteClassA extends AbstractClass {
    @Override
    protected void step2() {
        System.out.println("步骤2:A的实现");
    }
}

// 具体类B
public class ConcreteClassB extends AbstractClass {
    @Override
    protected void step2() {
        System.out.println("步骤2:B的实现");
    }

    @Override
    protected void step3() {
        System.out.println("步骤3:B的自定义实现");
    }
}

实际应用

数据导入模板

答案:

java
// 抽象导入类
public abstract class DataImporter {

    // 模板方法
    public final void importData(String filePath) {
        String data = readFile(filePath);
        List<Object> records = parseData(data);
        if (validateData(records)) {
            saveData(records);
            afterImport();
        }
    }

    private String readFile(String filePath) {
        System.out.println("读取文件: " + filePath);
        return "file content";
    }

    protected abstract List<Object> parseData(String data);
    protected abstract boolean validateData(List<Object> records);

    private void saveData(List<Object> records) {
        System.out.println("保存数据: " + records.size() + "条");
    }

    protected void afterImport() {
        // 默认不做任何处理
    }
}

// Excel导入
public class ExcelImporter extends DataImporter {
    @Override
    protected List<Object> parseData(String data) {
        System.out.println("解析Excel数据");
        return Arrays.asList("record1", "record2");
    }

    @Override
    protected boolean validateData(List<Object> records) {
        System.out.println("验证Excel数据");
        return true;
    }
}

Spring中的模板方法

JdbcTemplate?

答案:

java
// JdbcTemplate的execute方法
public <T> T execute(StatementCallback<T> action) {
    Connection con = DataSourceUtils.getConnection(getDataSource());
    Statement stmt = null;
    try {
        stmt = con.createStatement();
        T result = action.doInStatement(stmt);
        return result;
    } finally {
        JdbcUtils.closeStatement(stmt);
        DataSourceUtils.releaseConnection(con, getDataSource());
    }
}

练习题

  1. 模板方法模式和策略模式的区别?
  2. 什么时候使用钩子方法?
  3. 模板方法为什么要用final修饰?
  4. 如何避免模板方法过于复杂?
  5. 模板方法模式的应用场景有哪些?

Released under the MIT License.