5.2 模板方法
🚀 模式全景透视
设计哲学:好莱坞原则("别找我们,我们找你")的经典实践
杀伤力等级:⭐⭐⭐⭐⭐(高频面试模式Top3)
适用场景:
- 支付流程、工单审批等有固定流程的系统
- 需要统一埋点/日志等横切关注点
- 框架扩展点设计(如Spring JdbcTemplate)
🔍 模式解剖室(类图解析)
classDiagram
class OrderProcessor {
<<abstract>>
+processOrder() final
-validate()
-deliver()
+pay() abstract
#needLog() boolean
#logPayment()
}
class WechatOrderProcessor {
+pay()
+needLog() boolean
+logPayment()
}
class AlipayOrderProcessor {
+pay()
}
OrderProcessor <|-- WechatOrderProcessor
OrderProcessor <|-- AlipayOrderProcessor
🧪 实战升级:电商订单
需求变更风暴:
"要支持组合支付!国际站订单需要海关申报!虚拟商品无需物流!"
// 抽象模板增强版(应对复杂变更)
public abstract class OrderProcessor {
public final void processOrder() {
preCheck();
validate();
pay();
postPayment();
deliver();
afterSales();
}
private void preCheck() {
System.out.println("🔒 风控系统校验用户资质");
}
protected void validate() {
System.out.println("✅ 基础库存校验");
}
// 新增海关申报扩展点
protected void customsDeclaration() {}
// 支付组合策略
protected abstract void pay();
private void postPayment() {
System.out.println("📧 发送支付成功通知");
}
protected void deliver() {
System.out.println("🚚 默认物流配送");
}
protected void afterSales() {
System.out.println("📞 默认售后回访");
}
}
// 国际站订单实现
public class InternationalOrder extends OrderProcessor {
@Override
protected void validate() {
super.validate();
System.out.println("🌍 校验跨境商品许可证");
}
@Override
protected void pay() {
System.out.println("💶 组合支付:信用卡+PayPal");
}
@Override
protected void customsDeclaration() {
System.out.println("🛃 生成海关电子报关单");
}
@Override
protected void deliver() {
System.out.println("✈️ 国际空运+清关服务");
}
}
// 虚拟商品订单实现
public class VirtualOrder extends OrderProcessor {
@Override
protected void pay() {
System.out.println("🔑 虚拟货币支付");
}
@Override
protected void deliver() {
System.out.println("📩 发送电子兑换码至邮箱");
}
@Override
protected void afterSales() {
// 禁用默认售后
}
}
💣 设计模式地雷阵(常见错误)
-
过度抽象:
// 错误!将简单步骤拆分成多个抽象方法 public abstract class OverEngineeredProcessor { public final void process() { step1(); step2(); step3(); } abstract void step1(); abstract void step2(); abstract void step3(); }修复方案:仅对真正需要变化的步骤进行抽象
-
忽略final关键字:
// 危险!允许子类重写模板方法 public class ChaosProcessor extends OrderProcessor { public void processOrder() { // 完全破坏原有流程 } }防御措施:模板方法必须用final修饰
-
滥用钩子方法:
// 错误示范:钩子方法变成主流程控制 protected boolean shouldDeliver() { return globalConfig.get("deliverFlag"); }最佳实践:钩子方法只用于可选扩展,不承担核心逻辑
🧠 高频面试题深度解析
1. 模板方法模式在Spring框架中的应用?
- 答案示例:
JdbcTemplate是经典实现,其中execute()方法定义模板流程:- 获取连接
- 创建语句
- 执行SQL(抽象方法)
- 处理结果(可覆盖)
- 关闭资源
public class JdbcTemplate { public final Object query(String sql, RowMapper rowMapper) { // 模板方法流程... } protected Object extractData(ResultSet rs) { // 默认结果处理 } }
2. 如何处理模板方法中的异常?
- 策略建议:
① 在抽象类中定义异常处理钩子方法
② 使用模板方法+策略模式组合public abstract class RobustProcessor { public final void execute() { try { doExecute(); } catch (Exception e) { handleException(e); } } protected abstract void doExecute(); protected void handleException(Exception e) { // 默认异常处理 } }
3. 模板方法模式如何支持扩展开放/修改关闭原则?
- 技术解析:
通过固定模板方法(关闭修改)和抽象方法(开放扩展)的组合实现。
以Servlet生命周期为例:
开发者只需重写doGet/doPost,无需修改整体流程flowchart TD A[初始化init] --> B[处理请求service] B --> C[销毁destroy]
4. 模板方法模式与建造者模式的区别?
- 对比维度:
模板方法 建造者模式 控制方向 父类控制流程 指导者控制组装顺序 扩展维度 纵向扩展(子类实现步骤) 横向扩展(不同建造者) 典型应用 框架流程定义 复杂对象创建
🛠 重构实验室(实战演练)
原始代码(面条式代码):
public class PaymentService {
public void wechatPay() {
checkRisk();
log.info("微信支付开始");
// 微信支付逻辑
log.info("微信支付完成");
sendNotification();
}
public void aliPay() {
checkRisk();
log.info("支付宝支付开始");
// 支付宝支付逻辑
log.info("支付宝支付完成");
sendNotification();
}
}
重构步骤:
- 提取模板方法类
AbstractPaymentProcessor - 抽象支付核心方法
- 用钩子方法控制日志记录
- 最终代码:
public abstract class AbstractPaymentProcessor {
public final void process() {
checkRisk();
doPayment();
sendNotification();
}
private void checkRisk() {
// 风控校验逻辑
}
protected abstract void doPayment();
protected void sendNotification() {
// 默认短信通知
}
}
public class WechatPayment extends AbstractPaymentProcessor {
@Override
protected void doPayment() {
// 微信支付具体实现
}
@Override
protected void sendNotification() {
// 微信服务通知
}
}
📈 性能调优角斗场
场景:电商大促期间支付接口性能优化
模板方法优化策略:
- 缓存优化:在抽象类中增加缓存检查钩子
public abstract class CachedOrderProcessor extends OrderProcessor { @Override protected void validate() { if(checkCache()) return; super.validate(); } protected abstract boolean checkCache(); } - 异步扩展:将非核心步骤改为异步执行
public abstract class AsyncOrderProcessor extends OrderProcessor { @Override protected void deliver() { CompletableFuture.runAsync(super::deliver); } } - 熔断保护:在模板方法中集成熔断机制
public final void processOrder() { if(circuitBreaker.isOpen()) { fallback(); return; } // 正常流程... }