外观
一句话答案
父类定义算法骨架(abstract 方法),子类实现具体步骤,不改变算法结构;JdbcTemplate/RestTemplate 是典型。
核心要点
模板方法模式在父类中定义算法的骨架(执行流程),将某些步骤的实现延迟到子类。子类可以重新定义算法中的某些步骤,但不能改变算法的整体结构。
核心结构:
java
public abstract class AbstractTemplate {
// 模板方法:定义算法骨架,用 final 防止子类覆盖
public final void templateMethod() {
step1(); // 固定步骤(父类实现)
step2(); // 抽象步骤(子类实现)
if (hook()) { // 钩子方法(子类可选覆盖)
step3();
}
step4(); // 固定步骤
}
private void step1() { /* 固定实现 */ }
protected abstract void step2(); // 子类必须实现
protected boolean hook() { return true; } // 钩子:默认返回 true,子类可覆盖
protected abstract void step3();
private void step4() { /* 固定实现 */ }
}AQS 中的模板方法:
AbstractQueuedSynchronizer(AQS)是 Java 并发包的基础框架,典型的模板方法模式。→ 详见 Module 04
AQS 定义了获取/释放锁的模板方法(不可重写),子类只需实现尝试获取/释放的方法:
java
// AQS 的模板方法(final,不可重写)
public final void acquire(int arg) {
if (!tryAcquire(arg) && // ← 子类实现
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
public final boolean release(int arg) {
if (tryRelease(arg)) { // ← 子类实现
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
// 子类需要实现的方法(钩子)
protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); }
protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); }| AQS 子类 | 实现的方法 | 用途 |
|---|---|---|
ReentrantLock.Sync | tryAcquire / tryRelease | 可重入独占锁 |
Semaphore.Sync | tryAcquireShared / tryReleaseShared | 信号量 |
CountDownLatch.Sync | tryAcquireShared / tryReleaseShared | 倒计时门栓 |
Spring 中的模板方法:
JdbcTemplate:获取连接 → 执行 SQL(回调) → 释放资源AbstractApplicationContext.refresh():Spring 容器启动的 12 步固定流程RestTemplate:构建请求 → 执行请求 → 处理响应
模板方法 vs 策略模式:
| 维度 | 模板方法 | 策略模式 |
|---|---|---|
| 实现方式 | 继承(子类重写抽象方法) | 组合(传入不同策略对象) |
| 算法完整性 | 父类定义骨架,子类实现部分步骤 | 策略类实现完整算法 |
| 灵活性 | 编译期确定 | 运行时可动态切换 |
追问与易错
追问方向:
- 钩子方法是什么?
- 和策略模式区别?
- Spring 哪里用了模板方法?
易错点:
- ❌ 模板方法灵活性差——钩子方法提供扩展点
- ❌ 混淆模板方法和模板引擎
💡 记忆锚点
考试卷模式:老师定好卷面结构(选择题→填空→大题)用final锁死不许改顺序,学生只负责填空(实现abstract方法),钩子方法是附加题可做可不做。JdbcTemplate/AQS都是出好的卷子等你填答案。