模板方法:定义算法骨架
在基类中定义算法骨架,并让子类补充具体步骤
模板方法:定义算法骨架 是 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 反馈 — 无需本地设置。
此课程中的所有课时
- 观察者模式:事件通知
- 策略模式:可互换算法
- 命令模式:封装操作
- 模板方法:定义算法骨架