c#中工廠模式詳解

来源:https://www.cnblogs.com/mingnianjiehunba/archive/2023/11/03/17676347.html
-Advertisement-
Play Games

退款業務強耦合到售後系統中,並且業務代碼分散到各個業務層,嚴重缺乏系統的領域邊界和分層設計,重構後退款業務邏輯不強依賴售後核心業務邏輯,做到可以獨立部署。 ...


總體介紹:

  工廠模式主要有三種類型:簡單工廠工廠方法抽象工廠,該模式用於封裝管理對象的創建,是一種創建型模式

  萬物皆對象,創建對象時必然需要new該對象,當需要更改對象時,需要把項目中所有地方都修改一遍,這顯然違背了軟體設計的開閉原則。

  如果使用工廠來生成對象,那麼我們只需要跟工廠打交道就可以了。如果要更新對象時,直接在工廠里更換即可。這就實現了對象解耦

  所以工廠模式主要用來解耦代碼,將對象的創建使用分離,使得代碼更加靈活和可維護。

  定義創建對象的介面,讓其子類自己決定實例化哪一個工廠類,工廠模式使其創建過程延遲到子類進行。

  適用於創建對象需要大量重覆的步驟,或者需要依賴於其它對象的情況,它提供了一種方式來封裝多個相關或依賴對象的創建邏輯。

 

(一)簡單工廠基礎介紹:

  這是工廠模式的最基本形式,通過定義一個工廠類,它可以根據參數的不同返回不同類的實例,被創建的實例通常都具有共同的父類

  因為在簡單工廠模式中用於創建實例的方法是靜態(static)方法,因此簡單工廠模式又被稱為靜態工廠方法模式,它屬於類創建型模式,但不屬於GOF23種設計模式。

  簡單工廠包含三大角色:

  1. 抽象產品(抽象類):定義了產品的規範,描述了產品的主要特征和功能。它是工廠類創建的所有對象的父類,封裝了各種產品對象的共有方法
  2. 具體產品(子類):繼承抽象產品的子類,某個產品的具體實現類。
  3. 具體工廠(實例化對象類):它是簡單工廠模式的核心,負責實現創建所有產品實例的內部邏輯;其可以被外界直接調用,創建所需的產品對象。

      - 特性和功能:定義一個用於創建對象的介面,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。
     - 使用環境:當一個類不知道它所必須創建的對象的類的時候。
     - 註意事項:每增加一個產品就需要增加一個具體類和對象實現工廠,使得系統中類的個數成倍增加,在一定程度上增加了系統的複雜度。
     - 優點:一個調用者想創建一個對象,只要知道其名稱就可以了。
     - 缺點:增加新的產品需要修改工廠介面,違背了“開放-封閉原則”。

  簡單工廠創建方式:

  • 首先定義一個抽象產品類。
     1   /// <summary>
     2     /// 該類是產品的父類即抽象產品,定義所有子類的共有屬性和方法
     3     /// </summary>
     4     public abstract class Coffee
     5     {
     6         /// <summary>
     7         /// 方便演示,只定義兩個代表性方法。
     8         /// </summary>
     9         public abstract void GetName();
    10 
    11         public void AddSugar()
    12         {
    13             Console.WriteLine("加糖");
    14         }
    15     }

    該類主要定義了產品的共有屬性和方法,用於子類繼承和實現。

  • 其次定義每個產品的具體實現子類。
     1     public class AmericanCoffee : Coffee
     2     {
     3         public override void GetName()
     4         {
     5             Console.WriteLine("我是一杯美式咖啡。");
     6         }
     7     }
     8 
     9     public class LatterCoffe: Coffee
    10     {
    11         public override void GetName()
    12         {
    13             Console.WriteLine("我是一杯拿鐵咖啡。");
    14         }
    15     }

    該類實現並繼承自抽象類,如需增加產品可直接創建新的子類並繼承自抽象類即可。

  • 然後定義核心類,即工廠類。
     1     public class CoffeeFactory
     2     {
     3         public CoffeeFactory()
     4         {
     5         }
     6 
     7         /// <summary>
     8         /// 簡單工廠中必須要有一個方法來根據指定的邏輯創建實例
     9         /// </summary>
    10         /// <param name="fruitType"></param>
    11         /// <returns></returns>
    12         public static Coffee OrderCoffe(CoffeeEnum coffeeEnum)
    13         {
    14             switch (coffeeEnum)
    15             {
    16                 case CoffeeEnum.AmericanCoffee:
    17                     return new AmericanCoffee();
    18                 case CoffeeEnum.LatterCoffe:
    19                     return new LatterCoffe();
    20             }
    21             return null;
    22         }
    23 
    24         public enum CoffeeEnum
    25         {
    26             AmericanCoffee,
    27             LatterCoffe
    28         }
    29     }

    該類通過創建了一個枚舉類型參數來選擇需要創建的產品實例。

  • 最後客戶端調用。
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             //通過CoffeeFactory產品工廠創建了AmericanCoffee產品實例
     6             Coffee coffee = CoffeeFactory.OrderCoffe(CoffeeFactory.CoffeeEnum.AmericanCoffee);
     7             coffee.GetName();
     8 
     9             //通過CoffeeFactory產品工廠創建了LatterCoffe產品實例
    10             coffee = CoffeeFactory.OrderCoffe(CoffeeFactory.CoffeeEnum.LatterCoffe);
    11             coffee.GetName();
    12             coffee.AddSugar();
    13         }
    14     }

    根據客戶端的選擇條件來動態的實例化相關的類,

    對於客戶端來說,其去除了與具體產品之間的依賴。

    簡單工廠模式的缺點主要就是違背了開-閉原則

    在上面的 Demo 中,如果我要再增加一種產品。

    那麼,首先是定義一個新產品子類,讓其繼承自抽象類,然後呢,您還必須修改工廠類。

    所以進而改進形成了工廠方法模式

(二)工廠方法基礎介紹:

 這是一種更高級的工廠模式,它通過抽象介面基類中的工廠方法創建對象

  具體實現由子類負責,因此更加靈活。這種設計方式有利於實現開閉原則,即對擴展開放,對修改封閉

  簡單工廠把全部的事情,在一個地方(類)全部處理完,而工廠方法卻不同,

  定義一個用於創建對象的介面,讓子類決定實例化哪個產品類對象。工廠方法使一個產品類的實例化延遲到其工廠的子類。

  這樣一來,擴展產品種類就不必修改工廠函數了,核心類就變成抽象類,工廠方法模式將生成具體產品的任務分發給具體的產品工廠。

  也就是相當於工廠總部不生產產品了,交給下轄分工廠進行生產。

  要增加產品類時也要相應地增加工廠類,不需要修改工廠類的代碼了,這樣就解決了簡單工廠模式的缺點。

  工廠方法模式是簡單工廠模式的進一步抽象。由於使用了多態性,工廠方法模式保持了簡單工廠模式的優點,而且剋服了它的缺點。

  工廠方法模式的主要角色

      抽象工廠:在抽象工廠類中聲明瞭工廠方法,用於返回一個產品。提供了創建產品的介面,調用者通過它訪問具體工廠的工廠方法來創建產品。
      具體產品工廠:它是抽象工廠類的子類,實現了在抽象工廠中聲明的工廠方法,完成具體產品的創建。並可由客戶端調用,返回一個具體產品類的實例。
      抽象產品:它是定義產品的介面,定義了產品的規範,描述了產品的主要特性和功能,是工廠方法模式所創建對象的公共父類。
      具體產品:它實現了抽象產品介面,某種類型的具體產品由專門的具體工廠創建,具體工廠和具體產品之間一一對應。

  缺點:每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的複雜度。

  工廠方法創建方式:

  • 抽象產品類:
     1     /// <summary>
     2     /// 該類是產品的父類即抽象產品,定義所有子類的共有屬性和方法
     3     /// </summary>
     4     public abstract class Coffee
     5     {
     6         /// <summary>
     7         /// 方便演示,只定義兩個代表性方法。
     8         /// </summary>
     9         public abstract void GetName();
    10 
    11         public void AddSugar()
    12         {
    13             Console.WriteLine("加糖");
    14         }
    15     }
  • 具體產品類:
     1     public class AmericanCoffee : Coffee
     2     {
     3         public override void GetName()
     4         {
     5             Console.WriteLine("我是一杯美式咖啡。");
     6         }
     7     }
     8 
     9     public class LatterCoffe: Coffee
    10     {
    11         public override void GetName()
    12         {
    13             Console.WriteLine("我是一杯拿鐵咖啡。");
    14         }
    15     }
  • 抽象工廠:
    1     /// <summary>
    2     /// 抽象工廠
    3     /// </summary>
    4     public abstract class CoffeeFactory
    5     {
    6         public abstract Coffee GetCoffee();
    7     }
  • 具體產品工廠:
     1     /// <summary>
     2     /// 美式咖啡工廠
     3     /// </summary>
     4     public class AmericanFactory:CoffeeFactory
     5     {
     6         public override Coffee GetCoffee()
     7         {
     8             return new AmericanCoffee();
     9         }
    10     }
    11 
    12     /// <summary>
    13     /// 拿鐵咖啡工廠
    14     /// </summary>
    15     public class LatterFactory : CoffeeFactory
    16     {
    17         public override Coffee GetCoffee()
    18         {
    19             return new LatterCoffe();
    20         }
    21     }
  • 客戶端調用:
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             //首先創建一個美式咖啡工廠,只負責生產美式咖啡產品
     6             CoffeeFactory coffeeFactory = new AmericanFactory();
     7             //在美式咖啡工廠中生產一個美式咖啡產品
     8             Coffee coffee = coffeeFactory.GetCoffee();
     9             coffee.GetName();
    10 
    11             //創建一個拿鐵咖啡工廠,只負責生產拿鐵咖啡產品
    12             coffeeFactory = new LatterFactory();
    13             //在工廠中生產一個拿鐵咖啡產品
    14             coffee = coffeeFactory.GetCoffee();
    15             coffee.GetName();
    16             //咖啡中加糖
    17             coffee.AddSugar();
    18         }
    19     }

    通過客戶端調用方式可以看出,不同產品的生產由原來的總工廠變為了各個分工廠去負責。

    用戶只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體創建過程。

    在系統增加新的產品時只需要添加具體產品類和對應的具體工廠類,無須對原工廠進行任何修改,滿足開閉原則。

     

(三)抽象工廠基礎介紹:

  上面兩種模式不管工廠怎麼拆分抽象,都只是針對一類產品,直接生成實例,這些工廠只生產同種類產品。

  但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

  通俗點來講就是:簡單工廠和工廠方法模式的工作是生產產品,那麼抽象工廠模式的工作就是生產工廠的。

  是一種為訪問類提供一個創建一組相關或相互依賴對象的介面,且訪問類無須指定所要產品的具體類就能得到同族的不同等級的產品的模式結構。

  抽象工廠模式是工廠方法模式的升級版本,工廠方法模式只生產一個等級的產品,而抽象工廠模式可生產多個等級的產品。

  抽象工廠的最大好處在於交換產品系列非常方便,只需要改變具體工廠即可使用不同的產品配置。

  抽象工廠模式的主要角色

      抽象工廠:在抽象工廠類中聲明瞭多個工廠方法,用於返回多個產品。提供了創建產品的介面,它包含多個創建產品的方法,可以創建多個不同等級的產品。
      具體產品工廠:它是抽象工廠類的子類,實現了在抽象工廠中聲明的多個工廠方法,完成多個具體產品的創建。
      抽象產品:它是定義一個產品的介面,定義了一個產品的規範,描述了一個產品的主要特性和功能。抽象工廠模式有多個抽象產品。
      具體產品:實現了抽象產品角色所定義的介面,由具體工廠來創建,它同具體工廠之間是多對一的關係。

  總的來說工廠方法模式一個工廠只生產一個產品,抽象工廠模式一個工廠生產多個產品,形成一個產品套餐,而多個工廠組成套餐系列。

  抽象工廠創建方式:

  • 抽象產品類,有多少個不同產品就創建多少個抽象產品類。
     1     /// <summary>
     2     /// 咖啡產品抽象類
     3     /// </summary>
     4     public abstract class Coffee
     5     {
     6         /// <summary>
     7         /// 方便演示,只定義兩個代表性方法。
     8         /// </summary>
     9         public abstract void GetName();
    10 
    11         public void AddSugar()
    12         {
    13             Console.WriteLine("加糖");
    14         }
    15     }
    16 
    17     /// <summary>
    18     /// 甜點產品抽象類
    19     /// </summary>
    20     public abstract class Dessert
    21     {
    22         public abstract void GetName();
    23     }

    實例中創建了兩種產品,即咖啡和甜品。

  • 具體產品類,不同產品繼承不同抽象類。
     1     public class AmericanCoffee : Coffee
     2     {
     3         public override void GetName()
     4         {
     5             Console.WriteLine("我是一杯美式咖啡。");
     6         }
     7     }
     8 
     9     public class LatterCoffe: Coffee
    10     {
    11         public override void GetName()
    12         {
    13             Console.WriteLine("我是一杯拿鐵咖啡。");
    14         }
    15     }
    16 
    17     public class MatchaMousse: Dessert
    18     {
    19         public override void GetName()
    20         {
    21             Console.WriteLine("我是一塊抹茶慕斯。");
    22         }
    23     }
    24 
    25     public class Tiramisu: Dessert
    26     {
    27         public override void GetName()
    28         {
    29             Console.WriteLine("我是一塊提拉米蘇。");
    30         }
    31     }

    實例中定義了兩種咖啡和兩種甜點,咖啡為一個產品等級,甜點是另外一個產品等級。

  • 抽象工廠類,有多少個系列就可以創建多少個抽象工廠類。本實例只創建了一個風味系列的工廠。
     1     /// <summary>
     2     /// 風味工廠
     3     /// </summary>
     4     public abstract class RelishFactory
     5     {
     6         //生產一杯咖啡
     7         public abstract Coffee GetCoffee();
     8         //生產一塊甜點
     9         public abstract Dessert GetDessert();
    10     }

    實例中定義了一個系列的工廠,如果新增一個不同產品等級的奶茶,那就可以在風味工廠中生產一杯奶茶。同一種口味綁定為一個系列即一個抽象工廠

  • 具體工廠類,同一系列可以創建多個具體的工廠,負責同一系列下的不同產品出的創建。本實例創建了風味系列下的不同風味工廠的創建。
     1     /// <summary>
     2     /// 美式風味工廠
     3     /// </summary>
     4     public class AmericanRelishFactory : RelishFactory
     5     {
     6         public override Coffee GetCoffee()
     7         {
     8             return new AmericanCoffee();
     9         }
    10 
    11         public override Dessert GetDessert()
    12         {
    13             return new MatchaMousse();
    14         }
    15     }
    16 
    17     /// <summary>
    18     /// 義大利風味工廠
    19     /// </summary>
    20     public class ItalyRelishFactory : RelishFactory
    21     {
    22         public override Coffee GetCoffee()
    23         {
    24             return new LatterCoffe();
    25         }
    26 
    27         public override Dessert GetDessert()
    28         {
    29             return new Tiramisu();
    30         }
    31     }

    實例中創建了兩種不同口味的工廠,選擇對應口味的工廠,可以生產出對應口味的不同產品。

    比如選擇了美式口味工廠,該工廠可以生產出美式咖啡和抹茶慕斯。

    實際上是該工廠將這兩個不同等級的產品進行綁定,形成了一個產品族

  • 客戶端調用:
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             //首先創建一種口味工廠
     6             RelishFactory relishFactory = new AmericanRelishFactory();
     7             //然後對應口味工廠中生產出對應口味的不同產品。
     8             Coffee coffee = relishFactory.GetCoffee();
     9             coffee.GetName();
    10             Dessert dessert = relishFactory.GetDessert();
    11             dessert.GetName();
    12 
    13             Console.WriteLine("換一種口味");
    14             relishFactory = new ItalyRelishFactory();
    15             coffee = relishFactory.GetCoffee();
    16             coffee.GetName();
    17             dessert = relishFactory.GetDessert();
    18             dessert.GetName();
    19         }
    20     }

    實例中可以看出創建了一個美式口味工廠,

    該工廠就可以生產出符合該口味的不同產品。

    其本質就是將相同口味的不同產品綁定成一個產品族,形成一個產品族工廠。

    如果有多個產品族,那就創建多個產品族工廠就可以了。優點:當一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象。缺點:當產品族中需要增加一個新的產品時,所有的工廠類都需要進行修改。

總結:

簡單工廠把全部的事情,在一個地方(類)全部處理完,

而工廠方法卻不同,

其是通過創建一個框架,

然後讓子類決定要如何實現。

而抽象工廠則是定義一個負責創建一組產品(也就是一個產品族)的介面,

抽象工廠的最大好

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 10月30日,“速智未來 鷺島展翼”雲智超一體化算力推動數字廈門新跨越系列活動在福建廈門成功舉辦。省市政府部門領導、中國電信福建公司領導、各合作伙伴企業代表與天翼雲共聚一堂,活動現場舉行“速智未來 鷺島展翼”主題展、廈門市與天翼雲項目及福建電信戰略合作簽約儀式、“天翼雲杯”廈門算力應用大賽賽題徵集等... ...
  • 隨著大數據時代的到來,數據作為重要的生產要素和流動載體,如何加強技術層面的數據安全和隱私保護,對數據倉庫產品提出更高的要求。 ...
  • 根據北京研精畢智信息咨詢發佈的調查報告,2018-2021年,全球數據存儲量由30ZB上升至55ZB左右,年平均增長率約為27.8%。到2022年,數據總存儲量進一步增加至65ZB以上,較2021年同期新增了約10ZB,同比增長18.2%。各市場主體對數據的重視程度不斷提升,數據應用逐步由批量處理向 ...
  • 一、while語句 While 迴圈會在指定條件為真時迴圈執行代碼塊。 While迴圈,先進行條件判斷,再執行迴圈體的代碼 while (條件表達式){ 迴圈體 } 如果條件不滿足,則不會執行迴圈體,一次都不會 案例: var i= 1; while(i<=10){ console.log(i); ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 業務背景 由於當前項目中需要實現身份證拍照識別的功能,如果是小程式可以使用微信提供的 ocr-navigator 插件實現,但是在企業微信的H5中沒有提供該插件,所以需要手動實現該功能。 需求分析及資料查閱 眾所周知,前端H5中瀏覽器打開 ...
  • 本文將從三個方面來講解如何便捷配置出頁面,第一部分從數據、事件、業務支持三個方面進行分析,第二部分從模板與頁面收藏與升級、頁面UI結構、畫布功能三個方面進行分析,第三部分從監控、頁面配置、頁面數據導入導出以及其他能力四個方面進行分析。 ...
  • 案例一: 一百個和尚分一百個饅頭,大和尚一人分三個,小和尚三人分一個,正好分完。問大、小和尚各幾人? var num = 100; var people = 100; var big,small; for(big=0;big<=33;big++){ small=people-big; if(big* ...
  • QQ空間自動點贊評論腳本 F12 控制台 對於主頁用以下代碼 var x=5,y=10; function autoClick() { y=y+10+Math.floor(Math.random()*10); var zan = document.getElementsByClassName('it ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...