建造者模式將複雜物件建構與其表示分離,使相同建構過程可建立不同表示。本文以「建造小人」六步驟(頭、身、左手、右手、左腳、右腳)為例,詳解 Director 控制流程、Builder 介面、具體建造者與 C++ 實作。
Man),含多個組成部分。BuildHead 等)與 GetResult()。

#include <iostream>
using namespace std;
enum ManType { kFatMan, kThinMan, kNormal };
class Man {
ManType m_type;
public:
void SetHead(ManType t) { m_type = t; }
void SetBody(ManType t) { m_type = t; }
void SetLeftHand(ManType t) { m_type = t; }
void SetRightHand(ManType t) { m_type = t; }
void SetLeftFoot(ManType t) { m_type = t; }
void SetRightFoot(ManType t) { m_type = t; }
void ShowMan() {
switch (m_type) {
case kFatMan: cout << "I'm a fat man" << endl; break;
case kThinMan: cout << "I'm a thin man" << endl; break;
default: cout << "I'm a normal man" << endl;
}
}
};
class Builder {
public:
virtual ~Builder() {}
virtual void BuildHead() = 0;
virtual void BuildBody() = 0;
virtual void BuildLeftHand() = 0;
virtual void BuildRightHand() = 0;
virtual void BuildLeftFoot() = 0;
virtual void BuildRightFoot() = 0;
virtual Man* GetMan() = 0;
};
class FatManBuilder : public Builder {
Man *m_man;
public:
FatManBuilder() : m_man(new Man) {}
~FatManBuilder() { delete m_man; }
void BuildHead() override { m_man->SetHead(kFatMan); }
void BuildBody() override { m_man->SetBody(kFatMan); }
void BuildLeftHand() override { m_man->SetLeftHand(kFatMan); }
void BuildRightHand() override { m_man->SetRightHand(kFatMan); }
void BuildLeftFoot() override { m_man->SetLeftFoot(kFatMan); }
void BuildRightFoot() override { m_man->SetRightFoot(kFatMan); }
Man* GetMan() override { return m_man; }
};
class ThinManBuilder : public Builder {
Man *m_man;
public:
ThinManBuilder() : m_man(new Man) {}
~ThinManBuilder() { delete m_man; }
void BuildHead() override { m_man->SetHead(kThinMan); }
void BuildBody() override { m_man->SetBody(kThinMan); }
void BuildLeftHand() override { m_man->SetLeftHand(kThinMan); }
void BuildRightHand() override { m_man->SetRightHand(kThinMan); }
void BuildLeftFoot() override { m_man->SetLeftFoot(kThinMan); }
void BuildRightFoot() override { m_man->SetRightFoot(kThinMan); }
Man* GetMan() override { return m_man; }
};
class Director {
Builder *m_builder;
public:
Director(Builder *b) : m_builder(b) {}
void CreateMan() {
m_builder->BuildHead();
m_builder->BuildBody();
m_builder->BuildLeftHand();
m_builder->BuildRightHand();
m_builder->BuildLeftFoot();
m_builder->BuildRightFoot();
}
};
int main() {
Builder *builder = new FatManBuilder();
Director director(builder);
director.CreateMan();
Man *man = builder->GetMan();
man->ShowMan(); // I'm a fat man
delete man;
delete builder;
}
| 維度 | 建造者模式 | 抽象工廠模式 |
|---|---|---|
| 關注點 | 「如何一步步建構」複雜物件 | 「建立哪一族」相關物件 |
| 控制權 | Director 控制建構順序 | 客戶端直接呼叫工廠方法 |
| 產品回傳 | 建構完成後統一 GetResult() | 每個工廠方法即時回傳產品 |
| 典型場景 | 複雜物件建構(文檔轉換、遊戲角色、SQL 查詢建構) | UI 主題套件、資料庫驅動族、跨平台視窗建立 |
std::unique_ptr<Man> 管理產品生命週期,GetMan() 回傳 unique_ptr(移動語意)。virtual unique_ptr<Man> Build() 內部封裝所有步驟,簡化 Director。builder->BuildHead().BuildBody()... 回傳 *this,支援鏈式呼叫。建造者模式將「建構演算法」(Director)與「具體表示」(ConcreteBuilder)分離,支援同一流程產出不同產品。適合建構過程固定、部件組合變化大的複雜物件場景。