通俗易懂設計模式解析——抽象工廠模式

  • 2019 年 10 月 3 日
  • 筆記

前言

  前面介紹了單例模式及工廠模式相關知識及示例,今天主要介紹的是抽象工廠模式,上一篇我們講了工廠模式。將創建對象的任務委託給子類,延遲創建。解決工廠中責任的劃分。實現具體工廠與產品之間的一一對應。解決的是”單個對象”的問題。

  華為工廠除了生產華為手機之外。肯定也會有原件配套的充電線和耳機。這時工廠對應的是一套產品該如何解決了呢?顯然不再適合使用工廠模式了。今天將的抽象工廠模式將會比較好的解決此問題。抽象工廠模式解決的是”一系列對象”的問題、解決多套變化的問題。

抽象工廠模式介紹

一、來由

  在我們編程的過程中難免會出現”一系列相互依賴對象”的創建問題,往往會有由於需要的改變增加或減少對象的創建。為了面對解決這種”一系列的相互依賴的對象”的創建工作的緊密耦合性,出現了其解決方案——抽象工廠模式。

二、意圖

  提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。

三、案例圖

 

 

四、與工廠模式區別

工廠模式:

1、解決單個對象的問題

2、工廠類與產品類一一對應關係

抽象工廠模式:

1、解決一系列對象的問題

2、工廠類與產品類是一對多的關係(一對應一系列想依賴的產品)

工廠模式講的是一個華為手機工廠生產一個華為手機,要生產其他的產品需另加工廠。抽象工廠模式講的是一個華為手機工廠可以生產一系列的華為手機產品(手機、耳機、充電器)。

五、抽象工廠模式程式碼示例

  根據上一篇文章的事例我們進行擴展,進一步講述抽象工廠模式的使用。抽象工廠模式我們工廠類對應的多個產品的生產。華為手機工廠生產華為手機、華為耳機、華為充電器等。下面我們看看抽象工廠模式的具體實現:

 

namespace Abstract_Factory  {      #region 抽象產品類  ===============      /// <summary>      /// 手機抽象類      /// </summary>      public abstract class Phone      {          public abstract  string CreatePhone();      }      /// <summary>      /// 耳機抽象類      /// </summary>      public abstract class Headset      {          public abstract string CreateHeadset();      }      /// <summary>      /// 充電器抽象類      /// </summary>      public abstract class Charger      {          public abstract string CreateCharger();      }      #endregion        #region 華為具體產品類  ===========      public class HuaweiPhone : Phone      {          public override string CreatePhone()          {              return "華為手機一號現世";          }      }      public class HuaweiHeadset : Headset      {          public override string CreateHeadset()          {              return "華為手機一號原配耳機";          }      }      public class HuaweiCharger : Charger      {          public override string CreateCharger()          {              return "華為手機一號原配充電器";          }      }      #endregion        #region 小米具體產品類  ===========      public class XiaomiPhone : Phone      {          public override string CreatePhone()          {              return "小米手機一號現世";          }      }      public class XiaomiHeadset : Headset      {          public override string CreateHeadset()          {              return "小米手機一號原配耳機";          }      }      public class XiaomiCharger : Charger      {          public override string CreateCharger()          {              return "小米手機一號原配充電器";          }      }      #endregion        #region 抽象工廠類  ===============      /// <summary>      /// 抽象工廠類      /// </summary>      public abstract class AbstractFactory      {          public abstract Phone GetPhone();          public abstract Headset GetHeadset();          public abstract Charger GetCharger();      }      #endregion        #region 華為具體工廠===============      public class HuaweiFactory : AbstractFactory      {            public override Phone GetPhone()          {              return new HuaweiPhone();          }            public override Headset GetHeadset()          {              return new HuaweiHeadset();          }            public override Charger GetCharger()          {              return new HuaweiCharger();          }      }      #endregion        #region 小米具體工廠===============      public class XiaomiFactory : AbstractFactory      {            public override Phone GetPhone()          {              return new XiaomiPhone();          }            public override Headset GetHeadset()          {              return new XiaomiHeadset();          }            public override Charger GetCharger()          {              return new XiaomiCharger();          }      }      #endregion   }

 

    class Program      {          static void Main(string[] args)          {              ///華為工廠生產華為產品              HuaweiFactory huaweiFactory = new HuaweiFactory();              var phone = huaweiFactory.GetPhone().CreatePhone();              var headset = huaweiFactory.GetHeadset().CreateHeadset();              var charger = huaweiFactory.GetCharger().CreateCharger();              Console.WriteLine("華為產品生產:" + phone + "——" + headset + "——" + charger);                  ///小米工廠生產小米產品              XiaomiFactory xiaomiFactory = new XiaomiFactory();              phone = xiaomiFactory.GetPhone().CreatePhone();              headset = xiaomiFactory.GetHeadset().CreateHeadset();              charger = xiaomiFactory.GetCharger().CreateCharger();              Console.WriteLine("小米產品生產:" + phone + "——" + headset + "——" + charger);                  Console.ReadLine();          }      }

 

這是系列產品新增了一個魅族手機,我們看看如何修改增加魅族手機的生產:

    #region 新增魅族手機需求===========      public class MeizuPhone : Phone      {          public override string CreatePhone()          {              return "魅族手機一號現世";          }      }      public class MeizuHeadset : Headset      {          public override string CreateHeadset()          {              return "魅族手機一號原配耳機";          }      }      public class MeizuCharger : Charger      {          public override string CreateCharger()          {              return "魅族手機一號原配充電器";          }      }      public class MeizuFactory : AbstractFactory      {          public override Phone GetPhone()          {              return new MeizuPhone();          }          public override Headset GetHeadset()          {              return new MeizuHeadset();          }          public override Charger GetCharger()          {              return new MeizuCharger();          }        }      #endregion

 

            ///魅族工廠生產小米產品              MeizuFactory meizuFactory = new MeizuFactory();              phone = meizuFactory.GetPhone().CreatePhone();              headset = meizuFactory.GetHeadset().CreateHeadset();              charger = meizuFactory.GetCharger().CreateCharger();              Console.WriteLine("魅族產品生產:" + phone + "——" + headset + "——" + charger);

這裡我們可以發現新增系列產品(魅族系列)比較方便,而且吻合”開放擴展——封閉修改”的原則。擴展起來還是比較方便的,但是也是存在著一定的問題的。當我們新增新的產品的時候,這個時候就需要去系列產品生產抽象工廠去增加產品的生產方法。同時也需要在各個子類中增加其方法。這也就違背了開閉原則。這也就是抽象方法的一個缺點所在。

使用場景及優缺點

一、使用場景

1、在系統中如果存在一系列相互依賴的產品。這系列變化比較多。且存在著多套系列的產品的時候。我們就可以考慮使用抽象工廠模式了。

2、強調一系列相關的產品對象設計的時候。

3、一個系統由多個相互依賴項進行配置且需要多個系統時。

二、優點

1、當一個產品系列,對個對象使用時,保證使用的是同系列中的對象

2、降低了具體產品和具體類及客戶端之間的耦合性。通過使用抽象類相關聯而不是具體類。

3、對系列產品的修改增加極其方便

三、缺點

1、在系列產品中新增產品困難並且違反了開閉原則

總結

  到這裡抽象工廠模式我們就暫時的介紹完了。今天呢又介紹了創建型中的一種設計模式,設計模式的學習之路還很漫長。一切都才剛剛開始。學習更重要的是靈活運用,舉一反三。選擇適當的場景去使用適當的模式。多思考其優點缺點和使用場景。抽象工廠在針對於系列產品的修改增加時符合開閉原則。但是在系列產品中的產品修改增加的時候又違反了開閉原則。我們在使用每一種設計模式時都得慎重選擇。

   只要認為是對的就去做,堅持去做,不要在乎別人的看法,哪怕是錯,至少你有去做過證明曾經你努力過。

 

 

  C#設計模式系列目錄

 

歡迎大家掃描下方二維碼,和我一起踏上設計模式的闖關之路吧!