c#中建造者設計模式詳解

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

本節介紹Util應用框架對AspectCore AOP的使用. 概述 有些問題需要在系統中全局處理,比如記錄異常錯誤日誌. 如果在每個出現問題的地方進行處理,不僅費力,還可能產生大量冗餘代碼,並打斷業務邏輯的編寫. 這類跨多個業務模塊的非功能需求,被稱為橫切關註點. 我們需要把橫切關註點集中管理起來 ...


基礎介紹:

將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

  說白了就是將一個複雜的對象拆分成一個一個零件,然後按照既定順序和規則進行組裝,最終形成這個相對複雜的對象

  具體可分為4個角色:

    Product(產品):複雜對象本身。

    Builder(抽象建造者):既可以是抽象類也可以是介面,主要是為了約束和規範具體建造者有哪些零件,並提供一個方法返回組裝後的複雜對象。

    ConcreteBuilder(具體建造者):它繼承自Builder(抽象建造者),主要是具體實現父類中的那些零件。也就是說在這個類里就要實際去創建各個零件的具體功能了。

    Director(指揮者):又稱為導演類,在指揮者中不涉及具體產品的信息,只負責保證對象各部分完整創建或按某種順序創建。客戶端一般只需要與指揮者進行交互,在客戶端確定具體建造者的類型,並實例化具體建造者對象,然後通過指揮者類的構造函數或者Setter方法將該對象傳入指揮者類中。

  - 特性和功能:將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
  - 使用環境:當創建複雜對象的演算法應該獨立於該對象的組成部分以及它們的裝配方式時。
  - 註意事項:建造者模式的使用需要考慮其複雜性,如果產品結構較簡單,使用此模式可能會增加系統的複雜性。
  - 優點:客戶端不必知道產品內部組成的細節,將產品本身與產品的創建過程解耦。
  - 缺點:產品的組成部分必須相同,限制了其使用範圍。

應用場景:

  有時需要創建一個複雜對象,其通常由其各部分子對象通過一定的步驟組合而成。

  由於需求的變化,這個複雜對象的各個部分經常面臨著劇烈的變化,但是將它們組合在一起的演算法卻相對穩定。

  本質就是:創建的對象較複雜,由多個部件構成,各部件面臨著複雜的變化,但構件間的建造順序是穩定的。

  使得相同的創建過程可以創建不同的產品。

  造者模式所創建的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不適合使用建造者模式。

  • 垃圾食品套餐系統:漢堡、可樂、薯條、炸雞翅等是不變的,而其組合是經常變化的,生成出各種特惠"套餐"。
  • 裝修系統:改水電、再貼瓷磚、家電、電視牆等,順序基本不變,用材不同最終生成的產品則不同。
  • ......

創建方式:

  本實例主要是中Computer是產品,包含CPU、主板、記憶體、硬碟、顯卡、機箱等組件。

  Builder是抽象建造者,HighPerformanceBuilder和CostEffectiveBuilder是具體的建造者,Director是指揮者。

  1. 首先要確定產品類

    1     /// <summary>
    2     /// 產品類
    3     /// </summary>
    4     public class Computer
    5     {
    6         public string CPU { get; set; }
    7         public string Memory { get; set; }
    8         public string Disk { get; set; }
    9     }
    View Code
  2. 其次是抽象建造者類

     1     /// <summary>
     2     /// 抽象建造者類
     3     /// </summary>
     4     public abstract class BuilderComputer
     5     {
     6         //產品對象---protected關鍵字受保護成員可以在其所在的類、其子類以及同一個命名空間中的其他類中被訪問。
     7         protected Computer computer = new Computer();
     8 
     9         //以下方法約束了產品由哪些零件組成
    10         public abstract void BuildCPU();
    11         public abstract void BuildMemory();
    12         public abstract void BuildDisk();
    13 
    14         /// <summary>
    15         /// 返回對象本身
    16         /// </summary>
    17         /// <returns></returns>
    18         public Computer GetComputer()
    19         {
    20             return computer;
    21         }
    22     }
    View Code

    該類中限定了產品的組成部分也就是各個零件。

    這裡指明瞭產品由三個零件組成,分別是CPU、Disk和Memory。

  3. 再者是具體建造者類

     1     /// <summary>
     2     /// 低配電腦 具體的創建者
     3     /// </summary>
     4     class LowComputer : BuilderComputer
     5     {
     6         public override void BuildCPU()
     7         {
     8             computer.CPU = "i5處理器";
     9         }
    10 
    11         public override void BuildDisk()
    12         {
    13             computer.Disk = "512G固態";
    14         }
    15         public override void BuildMemory()
    16         {
    17             computer.Memory = "16G記憶體";
    18         }
    19     }
    20 
    21     /// <summary>
    22     /// 高配電腦 具體的創建者
    23     /// </summary>
    24     class GoodComputer : BuilderComputer
    25     {
    26         public override void BuildCPU()
    27         {
    28             computer.CPU = "i7處理器";
    29         }
    30 
    31         public override void BuildDisk()
    32         {
    33             computer.Disk = "1T固態";
    34         }
    35         public override void BuildMemory()
    36         {
    37             computer.Memory = "32G記憶體";
    38         }
    39     }
    View Code

    上述代碼中定義了兩個具體建造者,分別是低配電腦和高配電腦。

    繼承自抽象建造者類,並具體實現了其中的零件。

    如果還有還想新增其他配置點電腦,就可以新增一個具體建造者類,而無需修改其他代碼。

  4. 最後是指揮者

     1     /// <summary>
     2     /// 指揮者-監工 創建對象的順序
     3     /// </summary>
     4     public class Director
     5     {
     6         private BuilderComputer _builder = null;
     7 
     8         /// <summary>
     9         /// 通過構造函數傳遞具體創造者
    10         /// </summary>
    11         /// <param name="builder"></param>
    12         public Director(BuilderComputer builder)
    13         {
    14             this._builder = builder;
    15         }
    16 
    17         /// <summary>
    18         /// 組裝方法,並返回產品
    19         /// </summary>
    20         /// <returns></returns>
    21         public Computer AssembleComputer()
    22         {
    23             _builder.BuildCPU();
    24             _builder.BuildDisk();
    25             _builder.BuildMemory();
    26             return _builder.GetComputer();
    27         }
    28     }
    View Code

    在上述代碼中是通過構造函數傳遞具體創造者,也可以在AssembleComputer方法中傳遞。

    產品的具體組裝規則則是由AssembleComputer方法來完成,如果有多種組裝方式,也可以有多個方法來分別完成。

    該類本質就是統籌安排,並直接與客戶端進行交互。

  5. 客戶端調用
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             Console.WriteLine("我想組裝一臺低配電腦:");
     6             //首先實例化一個低配電腦的具體建造對象
     7             BuilderComputer builderComputer = new LowComputer();
     8             //然後使用指揮者類來具體組裝這個產品
     9             Computer director = new Director(builderComputer).AssembleComputer();
    10             Console.WriteLine("組裝完畢,具體配置如下:");
    11             Console.WriteLine(director.CPU);
    12             Console.WriteLine(director.Memory);
    13             Console.WriteLine(director.Disk);
    14 
    15 
    16             Console.WriteLine("\n我又想組裝一臺高配電腦:");
    17             //首先實例化一個高配電腦的具體建造對象
    18             builderComputer = new GoodComputer();
    19             //然後使用指揮者類來具體組裝這個產品
    20             director = new Director(builderComputer).AssembleComputer();
    21             Console.WriteLine("組裝完畢,具體配置如下:");
    22             Console.WriteLine(director.CPU);
    23             Console.WriteLine(director.Memory);
    24             Console.WriteLine(director.Disk);
    25 
    26         }
    27     }
    View Code

  6. 指揮者類也可以省略,組裝交給抽獎建造者來完成
     1     /// <summary>
     2     /// 抽象建造者類
     3     /// </summary>
     4     public abstract class BuilderComputer
     5     {
     6         //產品對象---protected關鍵字受保護成員可以在其所在的類、其子類以及同一個命名空間中的其他類中被訪問。
     7         protected Computer computer = new Computer();
     8 
     9         //以下方法約束了產品由哪些零件組成
    10         public abstract void BuildCPU();
    11         public abstract void BuildMemory();
    12         public abstract void BuildDisk();
    13 
    14         /// <summary>
    15         /// 可以省略掉指揮者類,由此方法進行組裝
    16         /// </summary>
    17         /// <returns></returns>
    18         public Computer Construct()
    19         {
    20             this.BuildCPU();
    21             this.BuildMemory();
    22             this.BuildDisk();
    23             return computer;
    24         }
    25     }
    View Code
     1     class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             Console.WriteLine("我想組裝一臺低配電腦:");
     6             Computer director = new LowComputer().Construct();
     7             Console.WriteLine("組裝完畢,具體配置如下:");
     8             Console.WriteLine(director.CPU);
     9             Console.WriteLine(director.Memory);
    10             Console.WriteLine(director.Disk);
    11 
    12 
    13             Console.WriteLine("\n我又想組裝一臺高配電腦:");
    14             director = new GoodComputer().Construct();
    15             Console.WriteLine("組裝完畢,具體配置如下:");
    16             Console.WriteLine(director.CPU);
    17             Console.WriteLine(director.Memory);
    18             Console.WriteLine(director.Disk);
    19 
    20         }
    21     }
    View Code

    在上述代碼中可以看出,此處還可以定義了一個虛方法,

    在具體建造者中,可以根據需要重寫該方法,使其返回實際需要的值,然後在構建過程中,使用該值進行構建。相較於指揮者類,具體產品的組裝可以交由產品本身去組裝。

總結:

  建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,並不適合使用建造者模式。

  建造者隱藏了具體產品的組裝過程,所以要改變一個產品的內部表示,只需要再實現一個具體的建造者就可以了,從而能很好地應對產品組成組件的需求變化。

  需要生產的產品對象有複雜的內部結構,這些產品對象通常包含多個成員變數,產品對象的屬性相互依賴,需要指定其生成順序。

  對象的創建過程獨立於創建該對象的類,隔離複雜對象的創建和使用,並使得相同的創建過程可以創建不同的產品。
  

附:創建者模式對比

  工廠模式解決了“同一類產品”的需求變化,抽象工廠模式解決了“系列產品”的需求變化,而建造者模式解決的是 “產品部分” 的需要變化。

 

  工廠方法模式 VS 建造者模式

  工廠方法模式側重整體對象的創建方式,建造者模式側重零部件的構建,然後通過一定順序和規則構造出一個複雜的對象。

  例如:想要製作一個假人,如果使用工廠方法模式,直接生產出來一個XX材質、XX高、XX重的假人人就可以了。

       而如果使用建造者模式,則需要先創建出四肢、頭和軀幹等部位,然後按照一定順序進行組裝形成一個完整的假人。

 

  抽象工廠模式 VS 建造者模式

  抽象工廠模式側重對產品族(系列產品)的創建,一個產品族是這樣的一系列產品。

  採用抽象工廠模式不需要關心構建過程,只關心什麼產品由什麼工廠生產即可。

  建造者模式則側重要求按照指定的藍圖建造產品,它的主要目的是通過組裝零配件而產生一個新產品。

  如果將抽象工廠模式看成汽車配件生產工廠,生產一個產品族的產品,那麼建造者模式就是一個汽車組裝工廠,通過對部件的組裝可以返回一輛完整的汽車。

  

  

作者:少年真愛 出處:https://www.cnblogs.com/mingnianjiehunba/p/17682403.html 博主的文章沒有高度、深度和廣度,只是湊字數。由於博主的水平不高,不足和錯誤之處在所難免,希望大家能夠批評指出。 博主是利用讀書、參考、引用、抄襲、複製和粘貼等多種方式打造成自己的文章,請原諒博主成為一個無恥的文檔搬運工!
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 隨著項目的發展,前端SPA應用的規模不斷加大、業務代碼耦合、編譯慢,導致日常的維護難度日益增加。同時前端技術的發展迅猛,導致功能擴展吃力,重構成本高,穩定性低。為了能夠將前端模塊解耦,通過相關技術調研,最終選擇了無界微前端框架作為物流客服系統解耦支持。為了更好的使用無界微前端框架,我們對其運行機制進... ...
  • 引言 前端性能已成為網站和應用成功的關鍵要素之一。用戶期望快速載入的頁面和流暢的交互,而前端框架的選擇對於實現這些目標至關重要。然而,傳統的前端框架在某些情況下可能面臨性能挑戰且存在技術壁壘。 在這個充滿挑戰的背景下,我們引入了 Qwik.js 框架。Qwik.js 不僅是一個前端框架,更是一種前端 ...
  • 本篇文章將解決上一篇文章 結尾遺留的問題:如何讓代碼自動實現響應性? 換句話說就是,如何讓我們的 effect 自動保存 & 自動重新運行?又如何攔截對象屬性的訪問和賦值操作? ...
  • 從接觸領域驅動設計的初學階段,到實現一個舊系統改造到DDD模型,再到按DDD規範落地的3個的項目。對於領域驅動模型設計研發,從開始的各種疑惑到吸收各種先進的理念,目前在技術實施這一塊已經基本比較成熟。在既往經驗中總結了一些在開發中遇到的技術問題和解決方案進行分享。 ...
  • 一、定義 運用共用技術有效地支持大量細粒度對象的復用,享元模式是一種結構型模式。 二、描述 享元模式要求能夠共用的對象必須是細粒度對象,因此它又稱為輕量級模式。享元模式的結構較為複雜,一般結合工廠模式一起使用,在其結構圖中包含了一個享元工廠類,包含以下四個角色: 1、Flyweight(抽象享元類) ...
  • 哈嘍大家好,我是鹹魚 想必大家都聽說過 Instagram ,它是全球最受歡迎的社交媒體平臺之一,擁有數十億的活躍用戶 Instagram 誕生於 2010 年,上線一周就坐擁 10 萬註冊用戶,一年之內就擁有了 1400 萬用戶,可見擴張趨勢突飛猛進。 Instagram 誕生的時候只有 3 個工 ...
  • 本節介紹Util應用框架如何進行驗證. 概述 驗證是業務健壯性的基礎. .Net 提供了一套稱為 DataAnnotations 數據註解的方法,可以對屬性進行一些基本驗證,比如必填項驗證,長度驗證等. Util應用框架使用標準的數據註解作為基礎驗證,並對自定義驗證進行擴展. 基礎用法 引用Nuge ...
  • 本文介紹了結構型設計模式中的橋接模式,講解了它的特點和相關構成,並通過相應的案例,使用Java代碼進行演示。 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...