設計模式 | 建造者模式

阿里雲開發者發表於2023-04-19
建造者模式是一種物件建立型模式,它將客戶端與包含多個部件的複雜物件的建立過程分離,客戶端無須知道複雜物件的內部組成部分與裝配方式,只需要知道所需建造者的型別即可。建造者模式關注如何逐步建立一個複雜的物件,不同的建造者定義了不同的建立過程,且具體建造者相互獨立,且更換建造者和增加建造者非常的方便,系統具有較好的擴充套件性。

1 | 建造者模式概述

無論是在現實世界中還是軟體系統中,都存在一些複雜的物件,他們擁有多個組成部分(部件),例如汽車,它包括車輪、方向盤、發動機等多種部件。對於大多數使用者而言,並不知道這些部件的裝配細節,也幾乎不會使用單獨某個部件,而是使用一輛完整的汽車。
思考:面對上面這種場景,如何將這些部件組裝成一輛完整的汽車並返回給使用者,而這種場景恰好就是建造者模式需要解決的問題。建造者模式可以將部件本身和它們的組裝過程分開,關注如何一步步建立一個包含多個組成部分的複雜物件,使用者只需要指定複雜物件的型別即可得到該物件,而無需知道其內部的具體構建細節。

1.1 建造者模式的定義

• 建造者模式:將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。
• Builder Pattern: Separate the construction of a complex object from its representation so that the same construction process can create different representations.
建造者模式是一種物件建立型模式,它將客戶端與包含多個部件的複雜物件的建立過程分離,客戶端無須知道複雜物件的內部組成部分與裝配方式,只需要知道所需建造者的型別即可。建造者模式關注如何逐步建立一個複雜的物件,不同的建造者定義了不同的建立過程,且具體建造者相互獨立,且更換建造者和增加建造者非常的方便,系統具有較好的擴充套件性。

2 | 建造者模式的結構與實現

2.1 建造者模式的結構

• (1) Builder(抽象建造者):它為建立一個產品 Product 物件的各個部件指定抽象介面,在該介面中一般宣告兩類方法,一類方法是 BuildPartX() (例如圖6-2中的 BuildPartA()、BuildPartB() 等),它們用於建立複雜物件的各個部件;另一類方法是GetResult(),它們用於返回複雜物件。Builder既可以是抽象類,也可以是介面。
• (2) ConcreteBuilder(具體建造者):它實現了 Builder 介面,實現各個部件的具體構造和裝配方法,定義並明確所建立的複雜物件,還可以提供一個方法返回建立好的複雜產品物件(該方法也可由抽象建造者實現)。
• (3) Product(產品):它是被構建的複雜物件,包含多個組成部件,具體建造者建立該產品的內部表示並定義它的裝配過程。
• (4) Director(指揮者):指揮者又稱為導演類,它負責安排複雜物件的建造次序,指揮者與抽象建造者之間存在關聯關係,可以在其 Construct() 建造方法中呼叫建造者物件的部件構造與裝配方法,完成複雜物件的建造。客戶端一般只需要與指揮者進行互動,在客戶端確定具體建造者的型別,並例項化具體建造者物件(也可以透過配置檔案和反射機制),然後透過指揮者類的建構函式或者 Setter 方法將該物件傳入指揮者類中。

2.2 建造者模式的實現

在構建模式的定義中提到了複雜物件,那什麼是複雜物件呢?簡單來說,複雜物件是指包含多個成員變數的物件,這些成員物件也稱為部件或零件。舉例:
• 汽車(複雜物件)包括:方向盤,車燈,發動機,輪胎,座椅等部件;
• 電子郵件(複雜物件)包括:發件人,收件人,主題,內容、附件等部件;
建造者模式的程式碼設計

using System;
namespace BuilderPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello BuilderPattern!");
            {
                Builder builder = new ConcreteBuilder1();
                Director director = new Director(builder);
                Product product = director.Construct(); //構建複雜物件
                Console.WriteLine($"【複雜物件】=> PartA:{product.PartA},PartB:{product.PartB},PartC:{product.PartC}");
            }
        }
    }
    #region BuilderPattern-Demo
    /// <summary>
    /// 產品
    /// </summary>
    class Product
    {
        public string PartA { get; set; }
        public string PartB { get; set; }
        public string PartC { get; set; }
    }
    /// <summary>
    /// 構建著 & 抽象類
    /// </summary>
    abstract class Builder
    {
        //建立產品物件
        protected readonly Product product = new Product();
        public abstract void BuildPartA();
        public abstract void BuildPartB();
        public abstract void BuildPartC();
        /// <summary>
        /// 返回產品物件
        /// </summary>
        /// <returns></returns>
        public Product GetResult()
        {
            return product;
        }
    }
    /// <summary>
    /// 具體構建者
    /// </summary>
    class ConcreteBuilder1 : Builder
    {
        public override void BuildPartA()
        {
            product.PartA = "A1";
        }
        public override void BuildPartB()
        {
            product.PartB = "B1";
        }
        public override void BuildPartC()
        {
            product.PartC = "C1";
        }
    }
    /// <summary>
    /// 指揮者
    /// </summary>
    class Director
    {
        private Builder _builder;
        public Director(Builder builder)
        {
            _builder = builder;
        }
        public void SetBuilder(Builder builder)
        {
            _builder = builder;
        }
        /// <summary>
        /// 產品構建與組裝方法
        /// </summary>
        /// <returns></returns>
        public Product Construct()
        {
            _builder.BuildPartA();
            _builder.BuildPartB();
            _builder.BuildPartC();
            return _builder.GetResult();
        }
    }
    #endregion
}

在指揮者類中可以注入一個抽象建造者型別的物件,它提供了一個建造者方法 Construct() ,在該方法中呼叫了 builder 物件的構造部件的方法,最後返回一個產品物件。

文章內容剩餘60%,完整內容請點選下方連結檢視:
https://developer.aliyun.com/article/1181900#slide-0

版權宣告:本文內容由阿里雲實名註冊使用者自發貢獻,版權歸原作者所有,阿里雲開發者社群不擁有其著作權,亦不承擔相應法律責任。具體規則請檢視《阿里雲開發者社群使用者服務協議》和《阿里雲開發者社群智慧財產權保護指引》。如果您發現本社群中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社群將立刻刪除涉嫌侵權內容。

相關文章