定義
將一個復雜物件的構建與它的表示分離,使得同樣的構建程序可以建造不同的表示,
建造者模式的結構
Builder(抽象建造者):它為創建一個產品Product物件的各個部件指定抽象介面,在該介面中一般宣告兩類方法,一類方法是BuildPartX(),他們用于創建復雜物件的各個部件,另一類方法是GetResult(),它們用于回傳復雜物件,Builder可以是抽象類,也可以是介面,
ConcreteBuilder(具體建造者):它實作了Builder介面,實作各個部件的具體構造和裝配方法,定義并明確所創建的復雜物件,還可以提供一個方法回傳創建好的復雜產品物件(該方法可以由抽象建造者實作),
Product(產品):它是被構建的復雜物件,包含多個組成部件,具體構造者創建該產品內部表示并定義它的裝配程序,
Director(指揮者):指揮者又稱為導演類,它負責安排復雜物件的構造次序,指揮者與抽象建造者之間存在關聯,可以在其Construct()建造方法中呼叫建造者物件的部件構造和裝備方法,完成復雜物件的構造,客戶端一般只需要與指揮者進行互動,在客戶端確認具體建造者的型別,并實體化具體建造者物件(也可以通過組態檔和反射機制),然后通過指揮者類的建構式或者Setter方法將物件傳入指揮者類中,有些時候Director不是必要的,例如你可以直接在抽象類中完成這個操作,
擼碼
汽車通常是由發動機、底盤、車身和電氣設備4大部分組成,
今天這個例子就以汽車為例,
Builder:CarBuilder
ConcreteBuilder:BenzCarBuilder,BMWCarBuilder,AudiCarBuilder
Product:汽車
Director:CarController
Product
首先好確認車子的組成部分(屬性)
/// <summary> /// Product /// </summary> public class Car { /// <summary> /// 發動機 /// </summary> public string Engine { get; set; } /// <summary> /// 底盤 /// </summary> public string Chassis { get; set; } /// <summary> /// 車聲 /// </summary> public string Body { get; set; } /// <summary> /// 電氣設備 /// </summary> public string Electrical { get; set; } }
Builder
抽象建造者類
/// <summary> /// 抽象建造者 /// </summary> public abstract class CarBuilder { protected Car _car; /* 抽象方法 */ public abstract void BuilderEngine(); public abstract void BuilderChassis(); public abstract void BuilderBody(); public abstract void BuilderElectrical(); public CarBuilder() { _car = new Car(); } public Car CreateCar() { return _car; }
ConcreteBuilder
具體的實作,這里為了避免代碼看起來很多我就只放兩個實作的Builder,
Audi
public class AudiCarBuilder : CarBuilder { public override void BuilderBody() { _car.Body = "豪華車身"; } public override void BuilderChassis() { _car.Chassis = "貴族底盤"; } public override void BuilderElectrical() { _car.Electrical = "史詩級電氣設備,100000000w超級噴射"; } public override void BuilderEngine() { _car.Engine = "行星級發動機"; } }
Benz
public class BenzCarBuilder : CarBuilder { public override void BuilderBody() { _car.Body = "鑲鉆車身"; } public override void BuilderChassis() { _car.Chassis = "真空底盤"; } public override void BuilderElectrical() { _car.Electrical = "100000000w超級噴射"; } public override void BuilderEngine() { _car.Engine = "恒星級發動機"; } }
CarController(指揮者)
/// <summary> /// 指揮者 /// </summary> public class CarController { /// <summary> /// 構建一輛汽車 /// </summary> /// <param name="builder"></param> /// <returns></returns> public Car Construct(CarBuilder builder) { //可以調整你想要的順序 builder.BuilderBody(); builder.BuilderChassis(); builder.BuilderElectrical(); builder.BuilderEngine(); return builder.CreateCar(); } }
最后測驗一下
CarController controller = new CarController(); //造一輛奧迪車 Car car = controller.Construct(new AudiCarBuilder()); Console.WriteLine(car.Body); Console.WriteLine(car.Chassis); Console.WriteLine(car.Electrical); Console.WriteLine(car.Engine);
結果

當然如果你的Car很多,就可以用一個列舉或者工廠去處理它,
總結
建造者模式的優點
1.在建造者模式,客戶端不必知道產品內部組成的細節,將產品本身和產品的創建程序解耦,使得相同的創建程序可以創建不同的產品物件,
2.每一個具體建造者都相對獨立,與其他的具體構造著無關,因此可以很方便的地替換具體建造者或增加新的建造者,用戶使用不同的具體建造者即可獲得不同的產品物件,由于建造者類針對抽象建造者編程,增加新的建造者無需修改原有類別庫的代碼,系統擴展方便,符合開閉原則,
3.用戶可以更加精細地控制產品的創建程序,將復雜產品的創建步驟分解到不同的方法中,使得創建程序更加清晰,也更方便使用程式來控制創建程序,
建造者模式的缺點
1.建造者模式所創建的產品一般具有較多的相同點,其組成方式很相似,如果產品之間的差異性很大,例如很多組成部分不相同,則不適合使用建造者模式,因此其適用范圍收到一定的限制,
2.如果產品的內部變化復雜,可能需要定義很多具體建造者來實作這種變化,導致系統變得很龐大,增加系統的理解難度和運行成本,
適用環境
1.需要生成的產品物件有復雜的內部結構,這些產品物件通常包含多個成員變數,
2.需要生成的產品物件屬性相互依賴,需要指定生成順序,
3.物件的創建程序獨立于創建該物件的類,在建造者模式中通過引入指揮者類,將創建程序封裝到指揮者類中,而不是在建造者類和客戶類,
4.隔離復雜物件的創建和使用,并使得相同的創建程序創建不同的產品,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/544145.html
標籤:設計模式
上一篇:如何從0開始搭建 Vue 組件庫
