【23種設計模式】抽象工廠模式(三)

2023-08-29 12:00:38

前言

在抽象工廠模式開篇之前,我們先思考一個問題,如果我們要設計一套房子,其他的元件暫時不考慮,我們僅僅考慮房頂、地板、窗戶、房門進行設計。什麼樣的風格暫時未知,可能會有很多種類。可以先設計一套古典風格的房子,再設計一套現代風格的房子,再設計一套歐式風格的房子....這麼多套房子需要設計,需求不斷變化,我們該怎麼才能後期的維護和擴充套件就更有利呢?那當然是減少使用者端程式碼與具體產品類之間的依賴,降低了系統的耦合度,這就是抽象工廠模式的優點之處。

抽象工廠模式定義

抽象工廠模式:提供一個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類。

  • 抽象產品類角色(AbstractProduct):為抽象工廠中相互依賴的每種產品定義抽象介面物件,也可以這樣說,有幾種產品,就要宣告幾個抽象角色,每一個抽象產品角色和一種具體的產品相匹配。
  • 具體產品類(ConcreteProduct):具體產品類實現了抽象產品類,是針對某個具體產品的實現的型別。
  • 抽象工廠類角色(Abstract Factory):定義了建立一組相互依賴的產品物件的介面操作,每種操作和每種產品一一對應。
  • 具體工廠類角色(ConcreteFactory):實現抽象類裡面的所有抽象介面操作,可以建立某系列具體的產品,這些具體的產品是「抽象產品類角色」的子類。

抽象工廠模式程式碼實現

抽象工廠模式的實現,只需要建立三個類:抽象工廠類,具體風格工廠類和具體產品風格實現類。當然也可以分離成四個類,將設計產品介面從抽象工廠分離出來。以設計歐式風格建築為例:

  • 建立抽象工廠類

     /// <summary>
        /// 抽象工廠類,提供建立不同型別房子的介面
        /// </summary>
        public abstract class AbstractFactory
        {
            /// <summary>
            /// 抽象工廠提供建立一系列產品的介面——抽象方法,這裡作為例子,只給出了房頂、地板、窗戶和房門建立介面
            /// 【1】房頂建立介面
            /// </summary>
            /// <returns></returns>
            public abstract Roof CreateRoof();
            /// <summary>
            /// 【2】地板建立介面
            /// </summary>
            /// <returns></returns>
            public abstract Floor CreateFloor();
            /// <summary>
            /// 【3】窗戶建立介面
            /// </summary>
            /// <returns></returns>
            public abstract Window CreateWindow();
            /// <summary>
            /// 【4】房門建立介面
            /// </summary>
            /// <returns></returns>
            public abstract Door CreateDoor();
        }
        
        #region 可以分離出來到單獨Class檔案的產品介面
        /// <summary>
        /// 房頂抽象類,子類的房頂必須繼承該類
        /// </summary>
        public abstract class Roof
        {
            /// <summary>
            /// 建立房頂
            /// </summary>
            public abstract void Create();
        }
    
        /// <summary>
        /// 地板抽象類,子類的地板必須繼承該類
        /// </summary>
        public abstract class Floor
        {
            /// <summary>
            /// 建立地板
            /// </summary>
            public abstract void Create();
        }
    
        /// <summary>
        /// 窗戶抽象類,子類的窗戶必須繼承該類
        /// </summary>
        public abstract class Window
        {
            /// <summary>
            /// 建立窗戶
            /// </summary>
            public abstract void Create();
        }
    
        /// <summary>
        /// 房門抽象類,子類的房門必須繼承該類
        /// </summary>
        public abstract class Door
        {
            /// <summary>
            /// 建立房門
            /// </summary>
            public abstract void Create();
        }
    
        #endregion
    
  • 建立歐式風格工廠

     /// <summary>
        /// 歐式風格房子的工廠,負責建立歐式風格的房子
        /// </summary>
        public class EuropeanFactory : AbstractFactory
        {
            // 製作歐式房頂
            public override Roof CreateRoof()
            {
                return new EuropeanRoof();
            }
    
            // 製作歐式地板
            public override Floor CreateFloor()
            {
                return new EuropeanFloor();
            }
    
            // 製作歐式窗戶
            public override Window CreateWindow()
            {
                return new EuropeanWindow();
            }
    
            // 製作歐式房門
            public override Door CreateDoor()
            {
                return new EuropeanDoor();
            }
        }
    
    
  • 建立歐式風格實現

     /// <summary>
        /// European 歐式風格建築
        /// </summary>
        public class European
        {
            /// <summary>
            /// 歐式地板類
            /// </summary>
            public class EuropeanFloor : Floor
            {
                public override void Create()
                {
                    Console.WriteLine("建立歐式的地板");
                }
            }
    
    
            /// <summary>
            /// 歐式的房頂
            /// </summary>
            public class EuropeanRoof : Roof
            {
                public override void Create()
                {
                    Console.WriteLine("建立歐式的房頂");
                }
            }
    
    
            /// <summary>
            ///歐式的窗戶
            /// </summary>
            public class EuropeanWindow : Window
            {
                public override void Create()
                {
                    Console.WriteLine("建立歐式的窗戶");
                }
            }
    
    
            /// <summary>
            /// 歐式的房門
            /// </summary>
            public class EuropeanDoor : Door
            {
                public override void Create()
                {
                    Console.WriteLine("建立歐式的房門");
                }
            }
    
        }
    
  • 歐式風格呼叫

     public void RunTest()
            {
                // 歐式風格的房子
                Console.WriteLine("開始設計歐式風格房子!");
                AbstractFactory europeanFactory = new EuropeanFactory();
                europeanFactory.CreateRoof().Create();
                europeanFactory.CreateFloor().Create();
                europeanFactory.CreateWindow().Create();
                europeanFactory.CreateDoor().Create();
            }
    

如果新需求設計新的風格房子,現代風格建築,只需要建立對應的具體實現工廠和具體產品分風格設計實現。

  • 建立現代風格工廠

     /// <summary>
        /// 現在風格房子的工廠,負責建立現代風格的房子
        /// </summary>
        public class ModernizationFactory : AbstractFactory
        {
            // 製作現代房頂
            public override Roof CreateRoof()
            {
                return new ModernizationRoof();
            }
    
            // 製作現代地板
            public override Floor CreateFloor()
            {
                return new ModernizationFloor();
            }
    
            // 製作現代窗戶
            public override Window CreateWindow()
            {
                return new ModernizationWindow();
            }
    
            // 製作現代房門
            public override Door CreateDoor()
            {
                return new ModernizationDoor();
            }
        }
    
  • 建立現代風格實現

      /// <summary>
        /// Modernization 現代風格建築
        /// </summary>
        public class Modernization
        {
    
            /// <summary>
            /// 現代的房頂
            /// </summary>
            public class ModernizationRoof : Roof
            {
                public override void Create()
                {
                    Console.WriteLine("建立現代的房頂");
                }
            }
    
            /// <summary>
            /// 現代的地板
            /// </summary>
            public class ModernizationFloor : Floor
            {
                public override void Create()
                {
                    Console.WriteLine("建立現代的地板");
                }
            }
    
            /// <summary>
            /// 現代的窗戶
            /// </summary>
            public class ModernizationWindow : Window
            {
                public override void Create()
                {
                    Console.WriteLine("建立現代的窗戶");
                }
            }
    
            /// <summary>
            /// 現代的房門
            /// </summary>
            public class ModernizationDoor : Door
            {
                public override void Create()
                {
                    Console.WriteLine("建立現代的房門");
                }
            }
    
        }
    
  • 現代風格呼叫

     public void RunTest()
            {
                // 歐式風格的房子
                Console.WriteLine("開始設計歐式風格房子!");
                AbstractFactory europeanFactory = new EuropeanFactory();
                europeanFactory.CreateRoof().Create();
                europeanFactory.CreateFloor().Create();
                europeanFactory.CreateWindow().Create();
                europeanFactory.CreateDoor().Create();
    
    
                //現代風格的房子
                Console.WriteLine("開始設計現代風格的房子!");
                AbstractFactory modernizationFactory = new ModernizationFactory();
                modernizationFactory.CreateRoof().Create();
                modernizationFactory.CreateFloor().Create();
                modernizationFactory.CreateWindow().Create();
                modernizationFactory.CreateDoor().Create();
            }
    

抽象工廠模式的優缺點

優點:

【抽象工廠模式】將系列產品的建立工作延遲到具體工廠的子類中,我們宣告工廠類變數的時候是使用的抽象型別,同理,我們使用產品型別也是抽象型別,這樣做就儘可能的可以減少使用者端程式碼與具體產品類之間的依賴,從而降低了系統的耦合度。耦合度降低了,對於後期的維護和擴充套件就更有利,這也就是【抽象工廠模式】的優點所在。

缺點:

【抽象工廠模式】很難支援增加新產品的變化,這是因為抽象工廠介面中已經確定了可以被建立的產品集合,如果需要新增新產品,此時就必須去修改抽象工廠的介面,這樣就涉及到抽象工廠類以及所有子類的改變,這樣也就違背了「開放—封閉」原則。