當一個物件的構建過程極其複雜(步驟多、順序敏感、參數組合爆炸),且需要根據不同需求產出不同「表示」(如:同樣「組裝電腦」流程,可產出「辦公機」、「遊戲機」、「伺服器」三種配置),建造者模式將構建算法與具體部件組裝解耦,實現「一套流程、多種產品」。
| 角色 | 職責 |
|---|---|
| Product | 最終產生的複雜物件(如 `Computer`) |
| Builder (Abstract) | 定義構建步驟介面(`buildCPU()`、`buildRAM()`、`buildStorage()`、`getResult()`) |
| ConcreteBuilder | 實作具體部件組裝邏輯,維護半成品狀態(`GamingComputerBuilder`、`OfficeComputerBuilder`) |
| Director | 封裝構建順序,呼叫 Builder 步驟,對客戶端隱藏細節 |
| Client | 建立 ConcreteBuilder → 注入 Director → 呼叫 `construct()` → 取得 Product |
// 產品:冰箱內容物清單
class FridgeContent {
public List Items { get; } = new List();
public override string ToString() => string.Join(" → ", Items);
}
// 抽象建造者:固定「開門 → 放入 → 關門」三步驟
abstract class PutIntoFridgeBuilder {
protected FridgeContent Content = new FridgeContent();
public abstract void OpenFridge();
public abstract void PutInto();
public abstract void CloseFridge();
public FridgeContent GetResult() => Content;
}
// 具體建造者:大象版
class ElephantBuilder : PutIntoFridgeBuilder {
private readonly string _name;
public ElephantBuilder(string name) => _name = name;
public override void OpenFridge() => Content.Items.Add("打開冰箱門");
public override void PutInto() => Content.Items.Add($"把 {_name} 裝進冰箱");
public override void CloseFridge() => Content.Items.Add("關上冰箱門");
}
// 具體建造者:過期牛奶版
class ExpiredMilkBuilder : PutIntoFridgeBuilder {
public override void OpenFridge() => Content.Items.Add("打開冰箱門");
public override void PutInto() => Content.Items.Add("放入過期牛奶");
public override void CloseFridge() => Content.Items.Add("關上冰箱門");
}
// 指揮者:統一流程
class Director {
private readonly PutIntoFridgeBuilder _builder;
public Director(PutIntoFridgeBuilder builder) => _builder = builder;
public void Construct() {
_builder.OpenFridge();
_builder.PutInto();
_builder.CloseFridge();
}
}
// 客戶端
class Program {
static void Main() {
var elephant = new ElephantBuilder("小象");
var director = new Director(elephant);
director.Construct();
Console.WriteLine(elephant.GetResult());
var milk = new ExpiredMilkBuilder();
director = new Director(milk);
director.Construct();
Console.WriteLine(milk.GetResult());
}
}
打開冰箱門 → 把 小象 裝進冰箱 → 關上冰箱門 打開冰箱門 → 放入過期牛奶 → 關上冰箱門
現代 C#/Java 常省略 Director,改用鏈式呼叫:
public class ComputerBuilder {
private string cpu, ram, storage, gpu;
public ComputerBuilder CPU(string v) { cpu = v; return this; }
public ComputerBuilder RAM(string v) { ram = v; return this; }
public ComputerBuilder Storage(string v) { storage = v; return this; }
public ComputerBuilder GPU(string v) { gpu = v; return this; }
public Computer Build() => new Computer(cpu, ram, storage, gpu);
}
// 使用
var pc = new ComputerBuilder()
.CPU("i9-13900K")
.RAM("64GB DDR5")
.Storage("2TB NVMe")
.GPU("RTX 4090")
.Build();
| 維度 | Builder | Abstract Factory | Prototype |
|---|---|---|---|
| 核心意圖 | 分步構建複雜物件 | 創建相關物件族群 | 複製現有實例 |
| 構建過程 | 多步驟、有序 | 單步驟、即時 | 零步驟、克隆 |
| 適用場景 | 參數多、順序敏感、多表示 | 產品族固定、等級固定 | 創建成本高、狀態少變 |
建造者模式是「複雜構建邏輯」的封裝器。記住:構建過程固定、表示多變 → Builder;產品族固定、等級固定 → Abstract Factory;複製比構建快 → Prototype。