cover

泡泡麵的流程是什麼?打開蓋子 → 放調味包 → 加熱水 → 等三分鐘。不管你泡的是辛拉麵還是花雕雞麵,這個流程都一樣——差別只在「調味包裡是什麼」。

Template Method Pattern 就是這個道理。

先講結論

父類別定義流程骨架(load → validate → parse → output),子類別只覆寫「不同的部分」。流程不會被子類別搞亂,但每一步的細節可以自由發揮。

classDiagram
    class DataProcessor {
        <<abstract>>
        +process(data) any
        +loadData(data)* any
        +validateData(data)* any
        +parseData(data)* any
        +outputResult(data) any
    }
    class CSVDataProcessor {
        +loadData(data) any
        +validateData(data) any
        +parseData(data) String[]
    }
    class JSONDataProcessor {
        +loadData(data) any
        +validateData(data) any
        +parseData(data) Object
    }
    DataProcessor <|-- CSVDataProcessor
    DataProcessor <|-- JSONDataProcessor
    note for DataProcessor "process() 定義固定流程\n子類別覆寫各步驟"

實戰:資料處理管線

處理 CSV 和 JSON 的步驟其實一模一樣,只是 parse 的方式不同。如果你寫了兩套完整的處理流程,那九成的 code 是重複的。

Template Method 模式:固定流程骨架搭配可替換步驟

class DataProcessor {
    // 這就是 template method——流程骨架,子類別不能改
    process(data) {
        const loaded = this.loadData(data);
        const validated = this.validateData(loaded);
        const parsed = this.parseData(validated);
        return this.outputResult(parsed);
    }
 
    loadData(data) { throw new Error('請實作 loadData'); }
    validateData(data) { throw new Error('請實作 validateData'); }
    parseData(data) { throw new Error('請實作 parseData'); }
 
    // hook method:子類別可以覆寫,也可以不覆寫
    outputResult(data) { return data; }
}
 
class CSVDataProcessor extends DataProcessor {
    loadData(data) {
        console.log('載入 CSV...');
        return data;
    }
    validateData(data) {
        console.log('驗證 CSV 格式...');
        return data;
    }
    parseData(data) {
        return data.split(',');
    }
}
 
class JSONDataProcessor extends DataProcessor {
    loadData(data) {
        console.log('載入 JSON...');
        return data;
    }
    validateData(data) {
        console.log('驗證 JSON 格式...');
        return data;
    }
    parseData(data) {
        return JSON.parse(data);
    }
}
 
const csv = new CSVDataProcessor();
csv.process('a,b,c,d'); // 走同一套流程,用 CSV 的方式 parse

Template Method vs Strategy

兩個都在處理「演算法可替換」,但方向相反:

  • Template Method:用繼承,父類別控制流程
  • Strategy:用組合,外部注入策略

如果你的流程骨架是固定的、只有個別步驟需要替換——用 Template Method。如果整個演算法都要替換——用 Strategy。


Template Method 就像 SOP 手冊——流程寫死在那,你只需要填空。問題是有些人填空也能寫出讓你看不懂的東西


延伸閱讀