模版方法模式

1、   基本概述算法

下面列出咖啡、茶的沖泡方法。數組

1.咖啡沖泡方法框架

(1)  把水煮沸ide

(2)  用沸水沖泡咖啡spa

(3)  把咖啡倒進杯子.net

(4)  家牛奶和糖設計

2.茶的沖泡方法code

(1)  把水煮沸對象

(2)  用沸水浸泡茶葉blog

(3)  把茶倒進杯子

(4)  加檸檬

在使用代碼來完成這些方法時,咱們通常想到的建立2個類(咖啡、茶類)來單獨實現這四個步驟。或者更好點是建立一個飲料父類來共享第一步與第三步,而後繼承父類實現各自飲料的第二步與第四步。那麼還有更好一點的方式來處理上面的問題嗎?有,可使用模版方法模式。

 

2、詳細說明

1.模版方法模式:在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中。模版方法使得子類能夠在不改變算法結構的狀況下,從新定義算法中的某些步驟。

這個模式是用來建立一個算法的模版。什麼是模版?如你所見,模版就是一個方法。更具體地說,這個方法將算法定義成一組步驟,其中的任何步驟均可以是抽象的,有子類負責實現。這能夠確保算法的結構保持不變,同時由子類提供部分實現。

 

 

 

鉤子是一種被聲明在抽象類中的方法,但只有空的或者默認的實現,鉤子的存在,可讓子類有能力對算法的不一樣點進行掛鉤。要不要掛鉤,由子類自行決定。

 

問:當我建立一個模版方法時,怎麼才能知道何時該使用抽象方法,何時使用鉤子呢?

答:當你的子類「必須」提供算法中某個方法或步驟的實現時,就使用抽象方法。若是算法的這個部分是可選的,就用鉤子。若是是鉤子的話,子類能夠選擇實現這個鉤子,但並不強制這麼作。

問:使用鉤子真正的目的是什麼?

答:鉤子有幾種用法。鉤子可讓子類實現算法中可選的部分,或者在鉤子對於子類的實現並不重要的時候,子類能夠對此鉤子置之不理。鉤子的另外一個用法,是讓子類可以有機會對模版方法中某些即將發生的步驟做出反應。鉤子也可讓子類有能力爲其抽象類做一些決定。

  如在Asp.net MVC框架中,你建立一個控制器,默認都是繼承Controller類,而Controller類中就有鉤子,如OnActionExecuted、OnActionExecuting、OnResultExecuted、OnResultExecuting等,這些鉤子可以在你的控制器中進行實現,以便控制或加工對請求的動做與返回的執行。

 

2.設計原則:好萊塢原則:別調用(打電話給)咱們,咱們會調用(打電話給)你。

    好萊塢原則能夠給咱們一種防止「依賴腐敗」的方法。當高層組件依賴底層組件,而底層組件又依賴高層組件,而高層組件又依賴邊側組件,而邊側組件有依賴底層組件時,依賴腐敗就發生了。在這種狀況下,沒有人能夠輕易地搞懂系統是如何設計的。

    在好萊塢原則之下,咱們容許底層組件將本身掛鉤到系統上,可是高層組件會決定何時和怎樣使用這些底層組件。換句話說,高層組件對待底層組件的方式是「別調用咱們,咱們會調用你」。

    好萊塢原則和模版方法之間的鏈接其實還算明顯:當咱們設計模版方法模式時,咱們告訴子類,「不要調用咱們,咱們會調用你」。

 

問:底層組件不能夠調用高層組件中的方法嗎?

答:並不盡然,事實上,底層組件在結束時,經常會調用從超類中繼承來的方法。咱們所要作的是,避免讓高層和底層組件之間有明顯的環狀依賴。

 

  模版方法模式是一個很常見的模式,處處都是。儘管如此,你必須擁有一雙銳利的眼鏡,由於模版方法有許多實現,而它們看起來並不必定和書上所說的設計一致。

  這個模式很常見是由於對建立框架來講,這個模式好用。有框架控制如何作事情,而由你(使用這個框架的人)指定框架算法中每一個步驟的細節。

如在C#數組中,有Array類提供一個Sort()方法用來排序,該方法有2個參數(一個是數組,一個是IComparer 接口),Sort方法提供了排序算法,實現IComparer 接口的參數提供了數組元素怎麼進行比較大小。

 

問:這真的是一個模版方法模式嗎?

答:咱們都知道,荒野中的模式並不是老是如同教科書例子通常地中規中矩,爲了符合當前的環境和實現的約束,它們老是要被適當地修改。這個Array類的Sort()方法的設計者受到一些約束,一般咱們沒法設計一個類繼承C#數組,而Sort()方法但願可以適用於全部的數組(每一個數組都是不一樣的類)。因此它們定義了一個靜態方法,而由被排序的對象內的每一個元素自行提供比較大小的算法部分。因此,這雖然不是教科書上的模版方法,但它的實現仍然符合模版方法模式的精神。再者,因爲不須要繼承數組可使用這個算法,這樣使得排序變得更有彈性、更有用。

4.總結:

1.好萊塢原則告訴咱們,將決策權放在高層模塊中,以便決定如何以及什麼時候調用底層模塊。

2.你將咋真實世界代碼中看到模版方法模式的許多變體,不要期待它們全都是一眼就能夠被你認出的。

3.策略模式和模版方法模式都封裝算法,一個用組合,一個用繼承。

4.工廠方法是模版方法的一種特殊版本。

3、代碼列表

public abstract class CaffeineBeverage
{
    public void PrepareRecipe()
    {
        BoilWater();
        Brew();
        PourInCup();
        AddCondiments();
        Hook();
    }

    protected abstract void Brew();

    protected abstract void AddCondiments();

    private void BoilWater()
    {
        Console.WriteLine("Boiling water");
    }

    private void PourInCup()
    {
        Console.WriteLine("Pouring into cup");
    }

    protected virtual void Hook()
    {
        
    }
}
public class Coffee:CaffeineBeverage
{
    protected override void Brew()
    {
        Console.WriteLine("沖泡咖啡");
    }

    protected override void AddCondiments()
    {
    }
    
}
public class Tea : CaffeineBeverage
{
    protected override void Brew()
    {
        Console.WriteLine("浸泡茶");
    }

    protected override void AddCondiments()
    {
        Console.WriteLine("加檸檬");
    }
}
View Code

---------以上內容根據《Head First Design Mode》進行整理

相關文章
相關標籤/搜索