建造者模式是一種物件建立型模式,它將客戶端與包含多個部件的複雜物件的建立過程分離,客戶端無須知道複雜物件的內部組成部分與裝配方式,只需要知道所需建造者的型別即可。建造者模式關注如何逐步建立一個複雜的物件,不同的建造者定義了不同的建立過程,且具體建造者相互獨立,且更換建造者和增加建造者非常的方便,系統具有較好的擴充套件性。
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
版權宣告:本文內容由阿里雲實名註冊使用者自發貢獻,版權歸原作者所有,阿里雲開發者社群不擁有其著作權,亦不承擔相應法律責任。具體規則請檢視《阿里雲開發者社群使用者服務協議》和《阿里雲開發者社群智慧財產權保護指引》。如果您發現本社群中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社群將立刻刪除涉嫌侵權內容。