IronMan之工廠
前言
實用為主,學一些用得到的技術更能在如今的社會里保命。 雖然在日常的工作中設計模式不是經常的用到,但是呢,學習它只有好處沒有壞處。
設計模式像是一種“標簽”,它是代碼編寫者思想的體現。有木有感覺到這樣很便捷?看到一些代碼的時候就很清楚的了解編寫者的思想了,這是為什么呢?因為編寫者們用了“標簽”,而你恰恰是知道“標簽”意思的。 跟一異曲同工,在學習框架、了解框架的對象模型的時候,“標簽”是時常出現,如果你不了解“標簽”的意思那多痛苦?。。。。?! 還有好多,不去一一闡述了。
工作中需求的變更時常令我們頭疼不已,總是要按著需求來重新的修改代碼,然后發布新的產品版本,或者是出更新包。 在需求變更中,對應著代碼也要修改,但是這修改也是分層次的。比如修改的模板在當初設計的時候遵循了開閉原則(OCP)的話,代碼的修改就變的輕松的多了。
我想制造出一個像電影《鋼鐵俠》里面那樣的的一身盔甲,又或者說是機器吧,我把這個想法告訴了我的朋友們,他們都認為我瘋了。
好吧,我說的是用代碼抽象的制造出”鋼鐵俠“
廢話不多說,下面這個系列是用鋼鐵俠(IronMan)作為主題的設計模式 今天來學習簡單工廠模式、工廠方法模式、以及抽象工廠模式。
問題的發現
需求:“玩具廠”有一天找到我說:“Jin叫獸我們這需要一些部件,我們會提供“圖紙”,請您幫忙制造,您看有問題嗎?”。我:“當然沒有問題了。很樂意幫助你們”。“玩具廠”:“噢!好的。Jin叫獸,時間方面還有什么問題嘛?”我:“沒問題的,我會盡快的”。“玩具廠”:“那真的太感謝您了,Jin叫獸。我們就不打擾您了,先走了。”我:“晚上一起吃頓飯吧”。“玩具廠”:“Jin叫獸不必客氣啊”。我:“好,你們慢走”。
生產車間:“一點挑戰性都沒有,隨隨便便就制造出來了。先從組成‘鋼鐵俠’的部件開始生產吧。”既然是這樣,那就從部件開始生產吧。這里是“玩具廠”提供的“鋼鐵俠”右臂的“圖紙”:
1 public class RightHandComponent 2 { 3 public RightHandComponent() 4 { 5 this.strName = "毅代先鋒號一代右部件"; 6 7 } 8 public RightHandComponent(string strname) 9 {10 this.strName = strname;11 }12 PRivate string strName = string.Empty;13 public string Name14 {15 get { return strName; }16 set { strName = value; }17 }18 }還有一個左臂部件的“圖紙”:
1 public class LeftHandComponent 2 { 3 public LeftHandComponent() 4 { 5 this.strName = "毅代先鋒號一代左部件"; 6 } 7 private string strName = string.Empty; 8 public string Name 9 {10 get { return strName; }11 set { strName = value; }12 }13 }還有若干“圖紙”…… 不在這篇一一列舉了,在后面文章中會全面的講解到。
開始生產
RightHandComponent rightcomponent = new RightHandComponent();LeftHandComponent leftcomponent = new LeftHandComponent();
若干的部件 被我一個個的按照圖紙給制造了出來。這樣就可以拿rightcomponent、leftcomponent……等等的一些制造好的部件組裝了。我也可以給“玩具廠”打電話了,可以交貨收錢。可是電話打完情況又變了,中間的對話就不說了,“玩具廠”的意思就是這樣的。比如說“運輸途中”出現“損壞”,他們希望用一個很快捷便利的方式能得到部件。
簡單工廠
嗯,我想了一下,不過對于我Jin叫獸來說都是小事,待我造出來一臺部件生產器來。他們拿著機器自己回家生產不就ok了。
public class IronManComponentFactory { public static object CreateComponent(string comname) { switch (comname) { case "RightCom": return new RightHandComponent(); case "LeftCom": return new LeftHandComponent(); 等等…… } return null; } }這樣生產的“機器”就好了,我得自己試用一下,看看效果怎么樣。
1 RightHandComponent rightcomponent = IronManComponentFactory.CreateComponent("RightCom") as RightHandComponent;2 LeftHandComponent leftcomponent = IronManComponentFactory.CreateComponent("LeftCom") as LeftHandComponent;這樣反而多此一舉了,第一步,向機器輸入了命令以便自己獲得想要的部件,第二步,在生產出來后我還得把“圖紙”拿過來比對一下。 在我一籌莫展的時候,“玩具廠”給我發了個郵件,給我發了一份“部件規范說明書”,要求我的機器生產出的部件是達到說明書標準的。
那我們就來看一下這個所謂的“部件規范說明書”
1 public abstract class Component 2 { 3 private string strName = string.Empty; 4 /// <summary> 5 /// 名稱 6 /// </summary> 7 public string Name 8 { 9 get { return strName; }10 set { strName = value; }11 }12 /// <summary>13 /// 自我描述14 /// </summary>15 public abstract void Self_Described();16 }看完這個“部件規范說明書”,我已經無力吐槽,沒辦法了,只有重新設計部件了,“圖紙”要重新繪制,因為要按照那該死的“規范說明書”。再看一下各個部件的“圖紙”
1 public class RightHandComponent:Component 2 { 3 public RightHandComponent() 4 { 5 base.Name = "毅代先鋒號一代右部件"; 6 //fWeight=材質輸出 7 } 8 public RightHandComponent(string strname) 9 {10 base.Name = strname;11 }12 public override void Self_Described()13 {14 Console.WriteLine(base.Name);15 }16 }17 public class LeftHandComponent:Component18 {19 public LeftHandComponent()20 {21 base.Name = "毅代先鋒號一代左部件";22 }23 public LeftHandComponent(string strname)24 {25 base.Name = strname;26 }27 public override void Self_Described()28 {29 Console.WriteLine(base.Name);30 }31 }等等一些部件……
這下我再把原來的搭好的“生產機器”拆了,內部修改一下,來看一下修改后的“機器”
1 public class IronManComponentFactory 2 { 3 public static Component CreateComponent(string comname) 4 { 5 switch (comname) 6 { 7 case "RightCom": 8 return new RightHandComponent(); 9 case "LeftCom":10 return new LeftHandComponent();11 12 }13 return null;14 }15 }自己來測試一下:
1 Component rightcomponent = IronManComponentFactory.CreateComponent("RightCom");2 Component leftcomponent = IronManComponentFactory.CreateComponent("LeftCom");3 rightcomponent.Self_Described();4 leftcomponent.Self_Described();于是,我很放心的就交給了“玩具廠”使用了,還得了個好評。
工廠方法
好景不長,“玩具廠”再次來電,提出一個要求,想讓我的“生產機器”里面還可以生產更多的符合“部件規范說明書”的部件。
這樣說來是要改裝“生產機器”了。 可以說“玩具廠”是故意的,絕對是故意的。這下整蒙圈了,虧血本了,“生產機器”又要拆了…… 直接來看“生產機器”的圖紙

1 public abstract class IronManComponentFactory 2 { 3 protected string factoryName = string.Empty; 4 protected void InitDataMessage() 5 { 6 Console.WriteLine("生產機器:" + factoryName + ".準備就緒"); 7 } 8 public abstract Component CreateComponent(); 9 }10 public class RightComFactory:IronManComponentFactory11 {12 13 public override Component CreateComponent()14 {15 base.factoryName = "右臂部件生產器";16 InitDataMessage();17 return new RightHandComponent();18 }19 }20 public class LeftComFactory:IronManComponentFactory21 {22 23 public override Component CreateComponent()24 {25 base.factoryName = "左臂部件生產器";26 InitDataMessage();27 return new LeftHandComponent();28 }29 }30 public class PottingFactrory31 {32 /// <summary>33 /// 取件口34 /// </summary>35 /// <param name="comFactory"></param>36 /// <returns></returns>37 public static Component ComExit(IronManComponentFactory comFactory)38 {39 if (comFactory != null)40 {41 return comFactory.CreateComponent();42 }43 return null;44 }45 }View Code
我們通過“取件口”取件
1 Component component = PottingFactrory.Com
新聞熱點
疑難解答