之前有篇部落格,介紹了“簡單原廠模式”。這篇部落格簡要的介紹一下“Factory 方法模式”。
簡介
定義一個使用者建立對象的介面,讓子類決定執行個體哪一個類。Factory Method使一個類的執行個體化延遲到子類。----------《設計模式》GOF
核心工廠類不再負責產品的建立,這樣核心類成為一個抽象工廠角色,僅負責具體工廠子類必須實現的介面,這樣進一步抽象化的好處是使得Factory 方法模式可以使系統在不修改具體工廠角色的情況下引進新的產品。
結構
舉例
之前《設計模式之0——簡單原廠模式》用了以下例子,現仍舉這個例子,但以Factory 方法來實現。:
某電視機廠專為各種電視機品牌代工生產各類電視機。當需要生產海爾電視時,只需要傳參“Haier”;當需要生產海信電視時,只需傳入“Hisense”。工廠根據傳入參數的不同返回不同品牌的電視機。
類圖
抽象產品類TV(電視機類):
public interface TV{ void play();}
具體產品類HisenseTV:
public class HisenseTV:TV{ public void play() { …… }}
具體產品類HaierTV:
public class HaierTV:TV{ public void play() { …… }}
抽象產品工廠介面:
interface ITVFactory{ TV CreateTV();}
具體產品工廠HaierTVFactory:
class HaierTVFactory : ITVFactory{ public TV CreateTV() { return new HaierTV(); }}
具體產品工廠HisenseTVFactory:
class HisenseTVFactory : ITVFactory{ public TV CreateTV() { return new HisenseTV(); }}
用戶端代碼:
class Program{ static void Main(string[] args) { ITVFactory fTV = new HaierTVFactory(); TV hTV = fTV.CreateTV(); hTV.play(); }}
對比簡單原廠模式
簡述
簡單原廠模式的最大優點在於工廠類中包含了必要的邏輯判斷,根據用戶端的選擇條件動態執行個體化相關的類,對於用戶端來說,去除了與具體產品的依賴。
Factory 方法模式實現時,用戶端需要決定執行個體化哪一個工廠來實現具體類,選擇判斷的問題還是存在的,也就是說,Factory 方法把簡單工廠的內部邏輯判斷移到了用戶端代碼來進行。想要加功能,本來是改工廠類的,現在是修改用戶端。
詳述
1. 結構複雜度
從這個角度比較,顯然簡單原廠模式要佔優。簡單原廠模式只需一個工廠類,而Factory 方法模式的工廠類隨著產品類個數增加而增加,這無疑會使類的個數越來越多,從而增加了結構的複雜程度。
2.代碼複雜度
代碼複雜度和結構複雜度是一對矛盾,既然簡單原廠模式在結構方面相對簡潔,那麼它在代碼方面肯定是比Factory 方法模式複雜的了。簡單原廠模式的工廠類隨著產品類的增加需要增加很多方法(或代碼),而Factory 方法模式每個具體工廠類只完成單一任務,代碼簡潔。
3.用戶端編程難度
Factory 方法模式雖然在工廠類結構中引入了介面從而滿足了OCP(開放-封閉原則),但是在用戶端編碼中需要對工廠類進行執行個體化。而簡單原廠模式的工廠類是個靜態類,在用戶端無需執行個體化,這無疑是個迷人的優點。
4.管理上的難度
這是個關鍵的問題。眾所周知,Factory 方法模式完全滿足OCP,即它有非常良好的擴充性。那是否就說明了簡單原廠模式就沒有擴充性呢?答案是否定的。簡單原廠模式同樣具備良好的擴充性——擴充的時候僅需要修改少量的代碼(修改工廠類的代碼)就可以滿足擴充性的要求了。儘管這沒有完全滿足OCP,但有時候不需要太拘泥於設計理論,可視情況而定。
5.維護性角度
然後我們從維護性的角度分析下。假如某個具體產品類需要進行一定的修改,很可能需要修改對應的工廠類。當同時需要修改多個產品類的時候,對工廠類的修改會變得相當麻煩(對號入座已經是個問題了)。反而簡單工廠沒有這些麻煩,當多個產品類需要修改時,簡單原廠模式仍然僅僅需要修改唯一的工廠類(無論怎樣都能改到滿足要求吧?大不了把這個類重寫)。