【原】從頭學習設計模式(三)——工廠方法模式

一、引入
本章我們來討論一下工廠方法模式,不同于“簡單工廠模式”,工廠方法模式可是23種設計模式中的正規軍。下面先引出工廠模式的標準定義。
工廠方法模式(Factory Method),定義一個用于創建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。說的通俗一點吧,就是把將工廠類抽象成接口,具體的代工廠去實現此接口,同時把產品類也抽象成接口,再構造具體的產品去實現些接口。
如果你學習了上一章“簡單工廠模式”的話,你就能很容易發現,工廠方法模式其實就是把簡單工廠中的工廠類進一步抽象,將一個大而全的工廠類拆成若干個互不相干的小工廠類,并且這些小工廠類都繼承自最上層最基礎的工廠類接口。
二、工廠模式的類圖
下面給出工廠方法模式的類圖結構,有助于理解。

三、代碼示例
上面的類圖中,在燈這個品類下,有燈泡和燈管兩種產品,并且都實現了燈的通用方法:關燈和開燈。在工廠類下,有各種生產具體產品的子工廠負責生產相應的兩種燈具。
如果還不是太明白,那我們來假設一個情景。小明(客戶端)想要買一個燈泡,他不認識工廠,只能去供銷店(工廠類)買,于是和老板說“我要一個燈泡”,老板說 “沒問題!您稍等”。轉身到了后院,對生產燈泡的小弟(燈泡工廠子類)吆喝一聲,給我造個燈泡!不一會燈泡造好了,老板拿給小明,“嘿嘿,燈泡給您作了一個,您試試?”,小明把燈泡擰在燈口上,開關了兩下(燈的通用方法)“嘿!挺好,沒問題!”,付了錢高高興興走了。
用代碼說明就是類似下面這樣:
/// <summary> /// 抽象的產品接口 /// </summary> public interface ILight { void TurnOn(); void TurnOff(); } /// <summary> /// 具體的產品類:燈泡 /// </summary> public class BulbLight:ILight { public void TurnOn() { Console.WriteLine("BulbLight turns on."); } public void TurnOff() { Console.WriteLine("BulbLight turns off."); } } /// <summary> /// 具體的產品類:燈管 /// </summary> public class TubeLight:ILight { public void TurnOn() { Console.WriteLine("TubeLight turns on."); } public void TurnOff() { Console.WriteLine("TubeLight turns off."); } } /// <summary> /// 抽象的工廠類 /// </summary> public interface ICreator { ILight CreateLight(); } /// <summary> /// 具體的工廠類:燈泡工廠 /// </summary> public class BulbCreator:ICreator { public ILight CreateLight() { return new BulbLight(); } } /// <summary> /// 具體的工廠類:燈管工廠 /// </summary> public class TubeCreator:ICreator { public ILight CreateLight() { return new TubeLight(); } }
/// <summary> /// 客戶端調用 /// </summary> /// <param name="args"></param> static void Main(string[] args) { //先給我來個燈泡 ICreator creator = new BulbCreator(); ILight light = creator.CreateLight(); light.TurnOn(); light.TurnOff(); //再來個燈管看看 creator = new TubeCreator(); light = creator.CreateLight(); light.TurnOn(); light.TurnOff(); }
四、總結
LZ認為應用工廠方法模式有以下的幾點好處:
首先,代碼結構清晰,裝封良好,客戶端調用只需要知道具體的工廠類名稱即可(如果命名非常規范,則只需要知道產品名稱就夠了),根本不用關心創建對象的復雜過程(示例中的代碼是很簡單的,但實際應用中創建和構造對象的過程可能會非常復雜),減少了模塊的耦合度。
其次,符合了“開放-關閉原則”的要求,在增加新產品的情況下,無需修改現有的產品類和工廠類,只要追加新的產品類和工廠類就夠了,系統的擴展性得到很大提升。這也彌補了“簡單工廠模式”的對修改開放的詬病。
再次,屏蔽了上層調用者和具體產品實現的牽連。不管產品的實現如何變化,只要接口不變,上層調用都不會跟著變化,只要修改相應的產品類或者產品工廠就夠了。
最后,工廠方法模式還滿足了迪米特原則,依賴倒轉原則,里氏替換原則,是典型的解耦框架。


浙公網安備 33010602011771號