HeadFirst 設計模式學習筆記8--模板方法模式

1.這個模式比較簡單,我們舉一個銀行貸款申請流程程序的例子(這個並非是書中的例子):

申請貸款,銀行要檢查這個客戶的一些事宜,譬如客戶收支狀況記錄、從三個地方拿到他的信用記錄、得到其他已有相關債務信息、得到借債人股票市值、得到借債人未來收入預期分析等等。我們可以設計如下一個模板方法:

我們的貸款類就可以如下這麼設計了,實現了模板方法中的抽象方法:

2.這個模式的核心思想是“抽象”。首先作爲模板方法,它必須是一個方法(廢話……),它可以作爲一個算法的例子,在模板方法中,每一個步驟都要由另一個方法來完成,某些方法是由這個類完成,某些則是由這個類的子類完成(需要由子類提供的方法必須在超類中聲明爲抽象)——模板方法定義了一個算法的步驟,並允許子類爲一個或多個步驟提供實現,實質上模板方法提供了一個算法的框架(Framework),步驟定死,而實現又子類進行。這個模式的優勢在於最大限度的發揮抽象能力,保證程序需求變更或者優化升級時必須進行的變更最小。注意、包含模板方法的類本身要是抽象的。

3.我們能不能比較智能的控制算法呢,比如某些時候這個客戶是一個VIP客戶,我們不需要對其Income去進行檢查,此時可以使用Hook(掛鉤),在需要的時候把一些方法“掛上”。我們這樣設計這個模板方法類:

掛鉤函數除了可以讓子類控制一些算法的流程以外,另一個功能是讓子類有機會對模板方法中某些即將發生的步驟做出反應。

注意,由於子類必須實現抽象類中的所有抽象方法,所以應該保持抽象方法的數目越少越好,這就需要你在設計的時候對算法內的數據不要切割太細,同時粒度太大程序的彈性又受到限制,這就需要你去權衡了,程序設計中太多的地方是平衡和妥協了。

4.我們此時引出一個新的OO原則——好萊塢原則:別電話給我們,我們會打電話給你——別調用我們,我們會去調用你。

在這個原則之下,我們允許低層組件將自己掛鉤到系統上,而高層組件會決定什麼時候和如何使用這些低層組件,我們把決策權放到高層模塊中。也就是說,高層組件對待低層組件的方式就是上邊那句黑體字的原則。書中舉了一個咖啡與茶的例子(有趣的是,《咖啡與茶》是丁薇早年間的一張唱片的名字,我高一的時候買到了正版卡帶)來解釋模板方法模式與這個原則關係,見原書(英文版)P297。這個原則和依賴倒置原則的關係是,後者交給我們如何儘量避免使用具體類,而多使用抽象,注重體現如何避免依賴。前者則是通過創建框架和組件的一種技巧,注重創建一個有彈性的設計,同時又防止其他類太過依賴它們,避免類的環狀依賴。值得注意的是,工廠方法是模板方法的一種特殊版本。

5.接着,我們看看Java中有什麼是使用了這個模式的:數組排序方法sort( )

sort()的設計者希望這個方法能適用於所有的數組,所以將其設置爲靜態方法。而同時你必須實現compartTo方法後才能使用sort方法,爲了達到這一點,設計者利用了Comparable接口,提供這個接口所聲明的方法,也就是compartTo。

我們現在利用這個接口去設計一個鴨子的類,試圖根據體重去對鴨子進行比較。

這樣,我們就能直接使用數組中的sort方法了:

這和模板方法又有什麼關係呢?

完成Comparable接口的compareTo方法使得元素自行提供比較大小的算法部分。這就有點像前邊我們的貸款程序中自己定義如何檢查客戶收入的函數一樣。

我們再舉兩個例子:Swing:

Applet:具體的applet大量使用掛鉤函數提供行爲。

6.最後,我們比較一下模板方法模式和策略模式的異同。

前者定義一個算法的大綱,由子類(注意這裏是繼承)定義其中的某些步驟的內容,這樣算法的細節可有不同,但是算法的結構和流程保持不變,它對算法有更多的控制權。而後者定義了一個算法的家族,並讓這些算法互換,正因爲每一個算法都被封裝了起來,所以客戶可以輕易地使用不同的算法(不是通過繼承而是接口的組合),它則更有彈性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章