****## 前言 在講述之工廠方法模式前,我們來先瞭解簡單工廠模式,簡單工廠模式是最簡單的設計模式之一,它雖然不屬於GoF的23種設計模式,但是應用也較為頻繁,同時它也是學習其他創建型模式的基礎。下麵我們來先瞭解下簡單工廠模式,然後針對它的缺點來引出工廠方法模式。 ## 簡單工廠模式定義 **簡單 ...
****## 前言
在講述之工廠方法模式前,我們來先瞭解簡單工廠模式,簡單工廠模式是最簡單的設計模式之一,它雖然不屬於GoF的23種設計模式,但是應用也較為頻繁,同時它也是學習其他創建型模式的基礎。下麵我們來先瞭解下簡單工廠模式,然後針對它的缺點來引出工廠方法模式。
簡單工廠模式定義
簡單工廠模式簡單來說就是創建一個工廠類,通過輸入的參數創建對象賦值給基類,完成對想要的派生類的調用,從而達成目標,具體的操作均在子類中完成,工廠類只負責運算邏輯和給基類賦值。在簡單工廠模式中,只需要記住一個簡單的參數即可獲得所需的對象實例,它提供專門的核心工廠類來負責對象的創建,實現對象的創建和使用分離。該模式有三部分:
- 工廠方法類:實現創建所有實例的選擇類型,被外界調用的介面。
- 抽象父類:所要創建的類的基類,描述類所有實例所共有的公共介面(方法),可以是抽象類也可是介面類型(interface),本例是抽象類。
- 具體子類:所有要創建的具體實例對象。
簡單工廠模式代碼實現
抽象產品類和工廠類合併,將靜態工廠方法移到抽象產品類中,根據不同的參數創建不同類型的產品子類對象。只需要添加配置文件並更改相關參數讀取參數即可,不要重新編譯程式。
-
引入NuGet包:
System.Configuration.ConfigurationManager
-
添加配置文件:
App.config
文件,追加內容<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <!--節點下添加配置,根據此配置,讀取參數決定創建哪個Product--> <add key="Product" value="B" /> </appSettings> </configuration>
-
創建抽象父類和具體子類
抽象類:包含工廠方法/// <summary> /// 【01】抽象工廠類 /// </summary> public abstract class Product { /// <summary> /// 靜態工廠方法 /// </summary> /// <param name="arg"></param> /// <returns></returns> public static Product GetProduct(string arg) { Product product = null; switch (arg) { case "A": product = new ProduceA(); break; case "B": product = new ProduceB(); break; //註意:有新產品需要修改工廠方法和創建新具體產品 default: throw new ArgumentException(message: "參數不合法"); } return product; } /// <summary> /// 所有產品類的公共業務方法 /// </summary> public void MethodSame() { Console.WriteLine("公共業務方法"); } /// <summary> /// 聲明抽象業務方法 /// </summary> public abstract void MethodDiff(); }
具體子類:
/// <summary> ///【02】具體工廠類A /// </summary> public class ProduceA : Product { /// <summary> /// 實現業務方法 /// </summary> public override void MethodDiff() { Console.WriteLine("產品A處理業務方法"); } }
/// <summary> ///【03】具體工廠類B /// </summary> public class ProduceB : Product { /// <summary> /// 實現業務方法 /// </summary> public override void MethodDiff() { Console.WriteLine("產品B處理業務方法"); } }
-
調用
/// <summary> /// 調用測試方法 /// </summary> public void RunTest() { //客戶端調用 var type = ConfigurationManager.AppSettings["product"];//根據配置文件中參數,傳入工廠方法,決定創建具體Product Product oneProduct = Product.GetProduct(type); oneProduct.MethodSame(); oneProduct.MethodDiff(); }
簡單工廠模式的優缺點
優點:
- 工廠類包含必要的邏輯判斷,可以決定在什麼時候創建哪一個產品類的實例,客戶端可以免除直接創建產品對象的職責,而僅僅“消費”產品,
- 簡單工廠模式實現了對象創建和使用的分離。
- 客戶端無須知道所創建的具體產品類的類名,只需知道具體產品類所對應的參數即可。
- 通過引入配置文件,可以在不修改任何客戶端代碼的情況下,更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。
缺點:
- 由於工廠類集中了所有產品的創建邏輯,職責過重,一旦不能正常工作,整個系統都要受到影響。
- 使用簡單工廠模式勢必會增加系統中類的個數,增加了系統的複雜度和理解難度。
- 系統擴展難度,一旦添加新產品不得不修改工廠邏輯,在產品類型加多時,有可能造成工廠邏輯過於複雜,不利於系統的擴展與維護。
- 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構。
簡單工廠模式小結
簡單工廠模式中,我們也發現了它的缺點,就是隨著需求的變化我們要不停地修改工廠裡面的方法的代碼,需求變化越多,裡面的If–Else–也越多,這樣就會造成簡單工廠的實現邏輯過於複雜。設計模式是遵循一定原則而得來的,比如,我們要怎麼增加代碼,怎麼修改代碼,其中一個原則就是OCP原則,中文是【開放關閉原則】,對增加代碼開放,對修改代碼關閉,所以我們就不能總是這樣修改簡單工廠裡面的方法。
工廠方法模式定義
工廠方法模式可以解決簡單工廠模式中存在的這個問題,定義一個用於創建對象的介面,讓子類決定實例化哪一個類。Factory Method使得一個類的實例化延遲到子類。
可以看出,在工廠方法模式的結構圖有以下角色:
-
抽象工廠(Creator): 充當抽象工廠角色,定義工廠類所具有的基本的操作,任何具體工廠都必須繼承該抽象類。
-
具體工廠(CreatorA):充當具體工廠角色,該類必須繼承抽象工廠角色,實現抽象工廠定義的方法,用來創建具體車。
-
抽象車(Car):充當抽象車角色,定義車類型所有具有的基本操作,具體車必須繼承該抽象類。
-
具體車(CarA):充當具體車角色,實現抽象車類對定義的抽象方法,由具體工廠類創建,它們之間有一一對應的關係。
簡單工廠模式的問題是:如果有新的需求,就需要修改工廠類裡面創建產品對象實例的那個方法的實現代碼,在面向對象設計一個原則就是哪裡有變化,我就封裝哪裡。
工廠方法模式代碼實現
-
抽象汽車類
/// <summary> /// 汽車抽象類 /// </summary> public abstract class Car { /// <summary> /// 開始行駛 /// </summary> public abstract void Go(); }
-
具體汽車類
/// <summary> /// ConcreteCar 具體車輛類 /// </summary> public class ConcreteCar { /// <summary> /// 紅旗汽車 /// </summary> public class HongQiCar : Car { public override void Go() { Console.WriteLine("紅旗汽車開始行駛了!"); } } /// <summary> /// 奧迪汽車 /// </summary> public class AoDiCar : Car { public override void Go() { Console.WriteLine("奧迪汽車開始行駛了"); } } }
-
抽象工廠
/// <summary> /// 抽象工廠類 /// </summary> public abstract class Factory { /// <summary> /// 工廠方法 /// </summary> /// <returns></returns> public abstract Car CreateCar(); }
-
具體工廠
/// <summary> /// ConcreteFactory 具體工廠方法 /// </summary> public class ConcreteFactory { /// <summary> /// 紅旗汽車工廠類 /// </summary> public class HongQiCarFactory : Factory { /// <summary> /// 負責生產紅旗汽車 /// </summary> /// <returns></returns> public override Car CreateCar() { return new HongQiCar(); } } /// <summary> /// 奧迪汽車工廠類 /// </summary> public class AoDiCarFactory : Factory { /// <summary> /// 負責創建奧迪汽車 /// </summary> /// <returns></returns> public override Car CreateCar() { return new AoDiCar(); } } }
-
調用
/// <summary> /// 測試方法 /// </summary> public void RunTest() { // 初始化創建汽車的兩個工廠 Factory hongQiCarFactory = new HongQiCarFactory(); Factory aoDiCarFactory = new AoDiCarFactory(); // 生產一輛紅旗汽車 Car hongQi = hongQiCarFactory.CreateCar(); hongQi.Go(); //生產一輛奧迪汽車 Car aoDi = aoDiCarFactory.CreateCar(); aoDi.Go(); }
工廠方法模式優缺點
優點:
- 在工廠方法中,用戶只需要知道所要產品的具體工廠,無須關係具體的創建過程,甚至不需要具體產品類的類名。
- 在系統增加新的產品時,我們只需要添加一個具體產品類和對應的實現工廠,無需對原工廠進行任何修改,很好地符合了“開閉原則”。
缺點:
- 每次增加一個產品時,都需要增加一個具體類和對象實現工廠,是的系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。這並不是什麼好事。
本文來自博客園,作者:碼農阿亮,轉載請註明原文鏈接:https://www.cnblogs.com/wml-it/p/17660891.html
技術的發展日新月異,隨著時間推移,無法保證本博客所有內容的正確性。如有誤導,請大家見諒,歡迎評論區指正!
開源庫地址,歡迎點亮:
GitHub:https://github.com/ITMingliang
Gitee: https://gitee.com/mingliang_it
GitLab: https://gitlab.com/ITMingliang
建群聲明: 本著技術在於分享,方便大家交流學習的初心,特此建立【編程內功修煉交流群】,為大家答疑解惑。熱烈歡迎各位愛交流學習的程式員進群,也希望進群的大佬能不吝分享自己遇到的技術問題和學習心得!進群方式:掃碼關註公眾號,後臺回覆【進群】。