0Pricing
Java Academy · 课时

模板方法:定义算法骨架

在基类中定义算法骨架,并让子类补充具体步骤

模板方法:定义算法骨架 是 CoddyKit 上的免费 Java Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。

模板方法的意图

模板方法在基类中定义算法的骨架,将某些步骤延迟到子类实现。子类可以重写这些步骤,而不改变整体结构。

抽象基类

基类包含模板方法(通常为 final),负责编排各个步骤。抽象方法表示可变化的步骤。具体方法提供默认行为。

public abstract class DataProcessor {
    // Template method — final, defines the algorithm
    public final void process() {
        readData();
        processData();
        writeResult();
    }
    protected abstract void readData();
    protected abstract void processData();
    protected void writeResult() {
        System.out.println("Result written (default)");
    }
}

具体子类

每个子类都实现抽象步骤。模板方法的执行顺序永远不变,只有各个步骤的具体实现会变化。

public class CSVProcessor extends DataProcessor {
    protected void readData()    { System.out.println("Reading CSV..."); }
    protected void processData() { System.out.println("Parsing CSV rows..."); }
}
public class XMLProcessor extends DataProcessor {
    protected void readData()    { System.out.println("Reading XML..."); }
    protected void processData() { System.out.println("Parsing XML nodes..."); }
    @Override
    protected void writeResult() { System.out.println("Writing XML result."); }
}

钩子方法

钩子是带有默认实现(通常为空实现)的可选步骤。子类可以重写钩子来添加可选行为,而不必被强制实现它。

public abstract class Game {
    public final void play() {
        initialize();
        while (!isDone()) takeTurn();
        printWinner();
    }
    protected void initialize() {}  // hook — optional override
    protected abstract boolean isDone();
    protected abstract void takeTurn();
    protected abstract void printWinner();
}

模板方法与策略

模板方法使用继承:骨架固定在基类中,各步骤由子类重写。策略使用组合:整个算法位于类的外部。策略更加灵活;当各步骤共享大量上下文时,模板方法更简单。

作为模板方法的 Java InputStream

java.io.InputStream 的 read(byte[], int, int) 以抽象方法 read() 为基础实现。子类实现单字节版本,多字节读取则是模板。

用于生成报告的模板方法

定义一个报告模板:收集数据、格式化数据,然后输出数据。替换子类即可生成 PDF、HTML 或 CSV 输出,而无需修改编排逻辑。

public abstract class ReportGenerator {
    public final String generate() {
        List<Record> data = fetchData();
        String body = format(data);
        return wrap(body);
    }
    protected abstract List<Record> fetchData();
    protected abstract String format(List<Record> data);
    protected String wrap(String body) { return body; } // hook
}

防止重写模板

将模板方法声明为 final,防止子类改变算法结构。只有钩子方法和抽象方法应该允许被重写。

public final void process() {
    validate(); // abstract
    execute();  // abstract
    cleanup();  // hook with default
}

抽象步骤与具体步骤

当某个步骤由子类提供是必须的时,将其设为抽象方法。当子类可以为了定制行为而重写某个步骤时,将其设为具体方法(也可以为空实现)。

JUnit 中的模板方法

JUnit 4 的 setUp() 和 tearDown() 是测试运行器定义的模板方法中的钩子。运行器控制调用它们的时机。

Spring 中的模板方法

Spring 的 JdbcTemplate 内部使用了模板方法。模板负责连接、语句创建和清理;您只需为变化的“映射行”步骤提供一个 RowMapper lambda。

List<User> users = jdbcTemplate.query(
    "SELECT * FROM users",
    (rs, row) -> new User(rs.getLong("id"), rs.getString("name"))
);

避免深层继承

模板方法依赖继承,这可能产生很深的类层次结构。请将层次限制在 1 到 2 层。如果子类开始以不同方式重写许多步骤,请考虑改用策略。

快速检查

哪个关键字可以防止子类改变模板方法的执行顺序?

回顾

模板方法使用 final 将算法骨架固定在基类中。子类实现抽象步骤,并可以选择重写钩子。保持层次结构浅显;需要更大灵活性时使用策略。

常见问题解答

「模板方法:定义算法骨架」课时是免费的吗?

是的 — 「模板方法:定义算法骨架」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。

「模板方法:定义算法骨架」这节课中我会学到什么?

在基类中定义算法骨架,并让子类补充具体步骤 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Java Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「模板方法:定义算法骨架」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Java Academy 课中编写并运行代码吗?

能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 观察者模式:事件通知
  2. 策略模式:可互换算法
  3. 命令模式:封装操作
  4. 模板方法:定义算法骨架
← 返回 Java Academy