1. 程式人生 > >JS設計模式之模板方法

JS設計模式之模板方法

介紹

模板方法(TemplateMethod)定義了一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。

模板方法是一種程式碼複用的基本技術,在類庫中尤為重要,因為他們提取了類庫中的公共行為。模板方法導致一種反向的控制結構,這種結構就是傳說中的“好萊塢法則”,即“別找我們,我們找你”,這指的是父類呼叫一個子類的操作,而不是相反。

正文

在例子中聊,泡茶和泡咖啡有同樣的步驟,比如燒開水(boilWater)、沖泡(brew)、倒在杯子裡(pourOnCup),加小料(addCondiments)等等。但每種飲料沖泡的方法以及所加的小料不一樣,所以我們可以利用模板方法實現這個主要步驟。

首先先來定義抽象步驟(模板):

var CaffeineBeverage = function () {

};
CaffeineBeverage.prototype.prepareRecipe = function () {
    this.boilWater();
    this.brew();
    this.pourOnCup();
    if (this.customerWantsCondiments()) {
        // 如果想加小料,就加上
         this.addCondiments();
    }
};
CaffeineBeverage.prototype.boilWater = function
() {
console.log("將水燒開!"); }; CaffeineBeverage.prototype.pourOnCup = function () { console.log("將飲料到再杯子裡!"); }; CaffeineBeverage.prototype.brew = function () { throw new Error("該方法必須重寫!"); }; CaffeineBeverage.prototype.addCondiments = function () { throw new Error("該方法必須重寫!"); }; // 預設加上小料
CaffeineBeverage.prototype.customerWantsCondiments = function () { return true; };

下面兩個函式分別是衝咖啡和沖茶所對應的函式:

// 衝咖啡
var Coffee = function () {
    CaffeineBeverage.apply(this);
};
Coffee.prototype = new CaffeineBeverage();
Coffee.prototype.brew = function () {
    console.log("從咖啡機想咖啡倒進去!");
};
Coffee.prototype.addCondiments = function () {
    console.log("新增糖和牛奶");
};
Coffee.prototype.customerWantsCondiments = function () {
    return confirm("你想新增糖和牛奶嗎?");
};

//沖茶
var Tea = function () {
    CaffeineBeverage.apply(this);
};
Tea.prototype = new CaffeineBeverage();
Tea.prototype.brew = function () {
    console.log("泡茶葉!");
};
Tea.prototype.addCondiments = function () {
    console.log("新增檸檬!");
};
Tea.prototype.customerWantsCondiments = function () {
    return confirm("你想新增檸檬嘛?");
};

使用confirm,可以讓使用者自己選擇加不加小料,很不錯嘛!

總結

模板方法應用於下列情況:

  1. 一次性實現一個演算法的不變的部分,並將可變的行為留給子類來實現
  2. 各子類中公共的行為應被提取出來並集中到一個公共父類中以避免程式碼重複,不同之處分離為新的操作,分別實現
  3. 控制子類擴充套件,模板方法可以只在特定點呼叫“Hook”操作,這樣就只允許在這些點進行擴充套件。

    注:
    鉤子(Hook)操作,它提供了預設的行為,子類在必要時進行擴充套件。一個鉤子操作的預設操作通常是一個空操作。在模板方法中應指明哪些操是鉤子操作(可以被重定義)以及哪些是抽象操作(必須被重定義)

和策略模式不同,模板方法使用繼承來改變演算法的一部分,而策略模式使用委託來改變整個演算法(這一點暫時不是很明白,學習策略模式後再回來理解)。