建造者模式(Builder Pattern)是23種經典設計模式中的創建型模式之一,其核心思想是將復雜對象的構建過程與其表示分離,使得同樣的構建流程可以生成不同結構或配置的對象。以下從定義、結構、應用場景、優缺點及代碼示例展開分析:
一、模式定義
建造者模式通過分步構建復雜對象,將對象的構造邏輯(如部件創建、組裝順序)封裝在獨立的建造者類中,客戶端只需指定建造者類型即可獲得最終產品,無需了解內部細節。
類比:如同在餐廳點餐,顧客只需選擇套餐類型(如A套餐、B套餐),廚師(建造者)會按固定流程準備食材(部件)并組合成完整餐品(產品)。
二、模式結構
建造者模式通常包含以下角色:
1.產品(Product)
復雜對象,由多個部件組成(如汽車由引擎、輪胎、車身等部件構成)。
2.抽象建造者(Builder)
定義創建產品各部件的抽象方法(如buildEngine()、buildWheel()),并提供獲取最終產品的方法(如getVehicle())。
3.具體建造者(ConcreteBuilder)
實現抽象建造者接口,具體定義部件的創建和組裝邏輯,返回不同配置的產品實例。
4.指揮者(Director)
封裝構建流程,調用建造者的方法按固定順序組裝產品(可選角色,客戶端也可直接調用建造者)。
三、應用場景
1.復雜對象構造
對象由多個部件構成,且部件創建步驟復雜(如計算機組裝需選擇CPU、內存、硬盤等)。
2.相同流程不同表示
構建過程穩定,但部件組合方式多樣(如汽車可組裝為SUV、跑車等不同型號)。
3.隔離構造與使用
客戶端無需關心對象內部細節,只需關注最終產品(如通過StringBuilder.append()逐步構建字符串,最后調用toString()獲取結果)。
4.可選部件處理
對象包含可選屬性,避免使用冗長的構造函數或Setter方法(如通過鏈式調用設置對象屬性)。
四、優缺點分析
1.優點
(1)解耦構建與表示:客戶端無需知道產品內部結構,只需指定建造者類型。
(2)擴展性強:新增具體建造者不影響現有代碼,符合開閉原則。
(3)控制構建細節:可靈活調整部件創建順序或條件(如根據配置選擇引擎類型)。
2.缺點
(1)類數量增加:需定義抽象建造者、具體建造者等額外類,系統復雜度上升。
(2)維護成本高:若產品內部結構變化,所有建造者均需修改。
(3)適用范圍有限:僅適用于部件數量多、構造過程復雜的對象。
五、代碼示例(C#)
以下是一個 完整的 C# 建造者模式示例,包含 產品類、抽象建造者、具體建造者、指揮者 和 客戶端調用,并支持 鏈式調用:
using System;// 1. 產品類(Computer)
public class Computer
{public string CPU { get; set; }public string RAM { get; set; }public string Storage { get; set; }public string GPU { get; set; }public bool HasKeyboard { get; set; }public bool HasMouse { get; set; }public override string ToString(){return $@"
Computer Configuration:CPU: {CPU}RAM: {RAM}Storage: {Storage}GPU: {GPU}Keyboard: {(HasKeyboard ? "Included" : "Not Included")}Mouse: {(HasMouse ? "Included" : "Not Included")}";}
}// 2. 抽象建造者(IComputerBuilder)
public interface IComputerBuilder
{IComputerBuilder SetCPU(string cpu);IComputerBuilder SetRAM(string ram);IComputerBuilder SetStorage(string storage);IComputerBuilder SetGPU(string gpu);IComputerBuilder IncludeKeyboard(bool include);IComputerBuilder IncludeMouse(bool include);Computer Build();
}// 3. 具體建造者(GamingComputerBuilder)
public class GamingComputerBuilder : IComputerBuilder
{private Computer _computer = new Computer();public IComputerBuilder SetCPU(string cpu) { _computer.CPU = cpu; return this; }public IComputerBuilder SetRAM(string ram) { _computer.RAM = ram; return this; }public IComputerBuilder SetStorage(string storage) { _computer.Storage = storage; return this; }public IComputerBuilder SetGPU(string gpu) { _computer.GPU = gpu; return this; }public IComputerBuilder IncludeKeyboard(bool include) { _computer.HasKeyboard = include; return this; }public IComputerBuilder IncludeMouse(bool include) { _computer.HasMouse = include; return this; }public Computer Build() { return _computer; }
}// 4. 指揮者(ComputerDirector)
public class ComputerDirector
{public Computer BuildGamingPC(IComputerBuilder builder){return builder.SetCPU("AMD Ryzen 9 5900X").SetRAM("64GB DDR4").SetStorage("2TB NVMe SSD").SetGPU("NVIDIA RTX 3080 Ti").IncludeKeyboard(true).IncludeMouse(true).Build();}public Computer BuildOfficePC(IComputerBuilder builder){return builder.SetCPU("Intel i5").SetRAM("16GB DDR4").SetStorage("512GB SSD").SetGPU("Integrated Graphics").IncludeKeyboard(false).IncludeMouse(false).Build();}
}// 5. 客戶端代碼
class Program
{static void Main(){// 使用指揮者構建標準配置var director = new ComputerDirector();var builder = new GamingComputerBuilder();Computer gamingPC = director.BuildGamingPC(builder);Computer officePC = director.BuildOfficePC(builder);Console.WriteLine("=== Standard Gaming PC ===");Console.WriteLine(gamingPC);Console.WriteLine("\n=== Standard Office PC ===");Console.WriteLine(officePC);// 直接鏈式調用自定義配置Computer customPC = new GamingComputerBuilder().SetCPU("Apple M1 Ultra").SetRAM("128GB").SetStorage("8TB SSD").SetGPU("AMD Radeon Pro").IncludeKeyboard(true).Build();Console.WriteLine("\n=== Custom PC ===");Console.WriteLine(customPC);}
}
關鍵設計點
1.鏈式調用
通過返回 IComputerBuilder 實現流暢接口(如 SetCPU().SetRAM().Build())。
2.指揮者
封裝固定構建流程(如 BuildGamingPC()),適合重復性構造。
3.靈活性
既可通過指揮者快速構建標準配置,也可直接鏈式調用自定義配置。
適用于需要 分步構建復雜對象 且 支持多種配置 的場景(如電腦、汽車、報表生成等)。
六、模式變體與實際應用
1.鏈式調用
通過方法返回this實現鏈式調用(如new Computer.Builder().cpu(“i9”).ram(“32GB”).build()),簡化客戶端代碼。
2.與工廠模式結合
工廠模式關注對象創建,建造者模式關注對象構造過程,兩者可結合使用(如先通過工廠獲取建造者,再調用建造者組裝產品)。
3.JDK中的應用
StringBuilder、StringBuffer均采用建造者模式,通過append()方法逐步構建字符串,最后調用toString()獲取結果。
七、總結
建造者模式適用于構造復雜對象的場景,通過解耦構建過程與產品表示,提升代碼的靈活性和可維護性。其核心優勢在于分步構建和精細控制,但需權衡類數量增加帶來的復雜度。在實際開發中,可根據對象復雜度選擇是否引入指揮者角色,或直接使用鏈式調用的簡化形式。