【原】從頭學習設計模式(四)——抽象工廠模式

一 、引入
前面我們討論了“簡單工廠模式”和“工廠方法模式”,這次我們來學習設計模式中最后的一種工廠模式——抽象工廠模式。
抽象工廠模式其實是工廠方法模式的一種擴展,應用抽象工廠模式可以創建一系列的產品(產品族),而不是像工廠方法模式中的只能創建一種產品。先我們來看一下抽象工廠模式的標準定義:
抽象工廠模式定義:為創建一組相關或相互依賴的對象提供一個接口,而且無需指定他們的具體類。
官方的定義一般都不易理解,我們就來模擬一個場景來說明一下這其中的關系吧。
富士康公司給兩個品牌作代工產品:蘋果和三星。眾所周知,這兩個品牌都有手機和平板產品,由于生產工藝的不同,富士康開設了兩條生產線,一條線只生產手機,另一條線只生產平板,總負責人是車間主任老王。一個賣蘋果設備的采購商找到老王,說先給我來1臺蘋果的iPad, 老王轉身到生產平板的生產線上的操作臺,往電腦里輸入“蘋果牌”三個字,很快1臺iPad生產出來了。采購商又說,再給我來1臺蘋果的iPhone吧,老王又轉身到手機的生產線,在電腦里輸入“蘋果牌”,很快一臺iPhone又造好了。
看出來了嗎?這里有兩種抽象的產品(蘋果產品和三星產品),而每種抽象的產品都有兩種產品角色(手機和平板電腦),這樣就要建立兩種工廠(手機工廠和平板工廠)分別負責不同產品角色的實例化。 老王就是工廠的總接口,他負責幫你找到正確的生產工廠,并且拿到你想要的那一種類型的產品。
每一個模式都是針對一定問題的解決方案,工廠方法模式針對的是一個產品等級結構,而抽象工廠模式針對的是多個產品等級結構。有多少個產品等級結構,就會在工廠角色中發現多少個工廠方法。每一個產品等級結構中有多少個具體的產品,就有多少個產品族,也就會在工廠等級結構中發現多少個具體工廠。總結一下我認為可以應用到抽象工廠模式的實際例子:
1. 兩種產品:PC和MAC,兩種產品等級:RAM,CPU
2. 兩種產品:水果和蔬菜,兩種產品等級:南方特產,北方特產
3. 兩種產品:男人和女人,三種產品等級:黃種人,黑人,白人
就類似這種結構的對象關系都可以用抽象工廠模式來構造。。。。。
二、類圖
下面是從百度百科里引用的類圖。

三、代碼會說話
用簡單的代碼來說明
1 /// <summary> 2 /// 蘋果產品系列 3 /// </summary> 4 public interface Apple 5 { 6 void AppleStyle(); 7 } 8 9 /// <summary> 10 /// 三星產品系列 11 /// </summary> 12 public interface Sumsung 13 { 14 void BangziStyle(); 15 } 16 17 public class iphone : Apple 18 { 19 public void AppleStyle() 20 { 21 Console.WriteLine("Apple's style: iPhone!"); 22 } 23 } 24 25 public class ipad : Apple 26 { 27 28 public void AppleStyle() 29 { 30 Console.WriteLine("Apple's style: iPad!"); 31 } 32 33 } 34 35 public class note2 : Sumsung 36 { 37 public void BangziStyle() 38 { 39 Console.WriteLine("Bangzi's style : Note2!"); 40 } 41 42 } 43 44 public class Tabs : Sumsung 45 { 46 public void BangziStyle() 47 { 48 Console.WriteLine("Bangzi's style : Tab!"); 49 } 50 } 51 52 public interface Factory 53 { 54 Apple createAppleProduct(); 55 Sumsung createSumsungProduct(); 56 } 57 58 /// <summary> 59 /// 手機工廠 60 /// </summary> 61 public class Factory_Phone : Factory 62 { 63 public Apple createAppleProduct() 64 { 65 return new iphone(); 66 } 67 68 public Sumsung createSumsungProduct() 69 { 70 return new note2(); 71 } 72 } 73 74 /// <summary> 75 /// 平板工廠 76 /// </summary> 77 public class Factory_Pad : Factory 78 { 79 public Apple createAppleProduct() 80 { 81 return new ipad(); 82 } 83 84 public Sumsung createSumsungProduct() 85 { 86 return new Tabs(); 87 } 88 }
模擬調用過程。
1 public static void Main(string[] args) 2 { 3 //采購商要一臺iPad和一臺Tab 4 Factory factory = new Factory_Pad(); 5 Apple apple = factory.createAppleProduct(); 6 apple.AppleStyle(); 7 Sumsung sumsung = factory.createSumsungProduct(); 8 sumsung.BangziStyle(); 9 10 //采購商又要一臺iPhone和一臺Note2 11 factory = new Factory_Phone(); 12 apple = factory.createAppleProduct(); 13 apple.AppleStyle(); 14 sumsung = factory.createSumsungProduct(); 15 sumsung.BangziStyle(); 16 17 Console.ReadKey(); 18 }
運行結果:

四、總結
抽象工廠模式最大的缺點就是對產品族的擴展非常困難,如果要添加一個新的品牌聯想的話,看看我們的改動會有多大吧。。。。 首先要在Factory接口中聲明新方法
Lenovo createLenovoProduct()
然后在所有現有的工廠實現類中分別實現這個新的createLenovoProduct()方法,如果工廠類有很多,改動的地方也會很多的。。違反了開閉原則,并且作為契約的接口修改了,其他所有和接口有關的代碼可能都要改。
反過來想,如果對產品角色擴展難不難呢?比如我要添加一個新的角色“電腦”,改動的地方有多少呢?只需要新建的各品牌電腦產品類和一個電腦工廠而已,都是擴展而不是修改,這樣就又符合了開閉原則。所以說,抽象工廠模式對于產品角色的擴展是很容易的。
到本章為止,設計模式中的所有工廠類的模式就都介紹完啦~ 邊學邊教,難免會有理解錯誤的地方,請大家幫我指正~


浙公網安備 33010602011771號