
模板方法模式屬於行為型模式,核心思想:**在父類定義算法骨架 (模板方法),將變化的步驟延遲到子類實現**,實現「好萊塢原則」——「別調用我們,我們會調用你」。
package com.roc.template;
public abstract class CarModel {
// 基本方法:由子類實現
protected abstract void start(); // 啟動
protected abstract void stop(); // 熄火
// 模板方法:final 防止被覆寫,鎖定算法骨架
final public void execute() {
this.start(); // 步驟 1
// 可在此插入通用邏輯:檢查油量、自檢...
this.stop(); // 步驟 2
}
}
package com.roc.template;
public class Wcar extends CarModel {
@Override
protected void start() {
System.out.println("大眾車啟動 ... 突突突");
}
@Override
protected void stop() {
System.out.println("大眾車熄火 ... 輕輕一扭");
}
}
package com.roc.template;
public class Ocar extends CarModel {
@Override
protected void start() {
System.out.println("奧迪 無鑰啟動 突突突");
}
@Override
protected void stop() {
System.out.println("奧迪 自動駐車熄火");
}
}
package com.roc.template;
public class Client {
public static void main(String[] args) {
CarModel wcar = new Wcar(); // 多態:父類引用指向子類物件
wcar.execute(); // 執行模板方法
CarModel ocar = new Ocar();
ocar.execute();
}
}
大眾車啟動 ... 突突突 大眾車熄火 ... 輕輕一扭 奧迪 無鑰啟動 突突突 奧迪 自動駐車熄火
isNeedLog() 決定是否記錄日誌)public abstract class DataProcessor {
// 模板方法
final public void process() {
readData();
if (needTransform()) { // Hook:子類可選擇是否轉換
transformData();
}
saveData();
}
protected abstract void readData();
protected abstract void saveData();
protected void transformData() {} // 預設空實現
// Hook 方法:回傳 boolean 控制流程
protected boolean needTransform() {
return true; // 預設需轉換,子類可覆寫
}
}
| 優點 | 缺點 |
|---|---|
| 封裝不變部分,擴展變化部分 | 類數量增加,系統較大時類爆炸 |
| 提取公共代碼,便於維護 | 反向控制結構增加理解難度 |
| 受控擴展點,符合開閉原則 | 父類修改可能影響所有子類 |
經典應用:HttpServlet.service()(模板方法) →doGet/doPost(基本方法);AbstractList、InputStream、SpringJdbcTemplate、MyBatisBaseExecutor等框架大量使用。