將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。

BuildPartA(), BuildPartB()。Construct(),呼叫 Builder 步驟,不依賴具體 Builder。#ifndef BUILDER_H
#define BUILDER_H
class Builder {
public:
Builder() {}
virtual ~Builder() {}
virtual void BuildPartA() = 0;
virtual void BuildPartB() = 0;
};
class Director {
public:
Director(Builder* pBuilder);
~Director();
void Construct();
private:
Builder* m_pBuilder;
};
class ConcreteBuilder1 : public Builder {
public:
ConcreteBuilder1() {}
virtual ~ConcreteBuilder1() {}
virtual void BuildPartA();
virtual void BuildPartB();
};
class ConcreteBuilder2 : public Builder {
public:
ConcreteBuilder2() {}
virtual ~ConcreteBuilder2() {}
virtual void BuildPartA();
virtual void BuildPartB();
};
#endif
#include "Builder.h"
#include <iostream>
void ConcreteBuilder1::BuildPartA() { std::cout << "BuildPartA by ConcreteBuilder1\n"; }
void ConcreteBuilder1::BuildPartB() { std::cout << "BuildPartB by ConcreteBuilder1\n"; }
void ConcreteBuilder2::BuildPartA() { std::cout << "BuildPartA by ConcreteBuilder2\n"; }
void ConcreteBuilder2::BuildPartB() { std::cout << "BuildPartB by ConcreteBuilder2\n"; }
Director::Director(Builder* pBuilder) : m_pBuilder(pBuilder) {}
Director::~Director() { delete m_pBuilder; m_pBuilder = nullptr; }
void Director::Construct() {
m_pBuilder->BuildPartA();
m_pBuilder->BuildPartB();
}
#include "Builder.h"
#include <cstdlib>
int main() {
Builder* pBuilder1 = new ConcreteBuilder1();
Director* pDirector1 = new Director(pBuilder1);
pDirector1->Construct();
Builder* pBuilder2 = new ConcreteBuilder2();
Director* pDirector2 = new Director(pBuilder2);
pDirector2->Construct();
delete pDirector1; delete pDirector2;
return 0;
}
| 維度 | Builder | Abstract Factory |
|---|---|---|
| 焦點 | 複雜物件「分步驟構建過程」 | 「系列相關物件」創建 |
| 回傳時機 | 構建完成後一次取得產品 | 每個創建方法即時回傳 |
| 流程控制 | Director 掌握順序 | 客戶端自行決定順序 |
| 典型案例 | 文檔轉換(HTML/PDF/RTF)、SQL 查詢建構器、HTTP 請求建構器 | 跨平台 UI 元件庫、資料庫驅動族群 |
class HttpRequestBuilder {
HttpRequest req;
public:
HttpRequestBuilder& SetUrl(string url) { req.url = url; return *this; }
HttpRequestBuilder& AddHeader(string k, string v) { req.headers[k] = v; return *this; }
HttpRequestBuilder& SetBody(string body) { req.body = body; return *this; }
HttpRequest Build() { return std::move(req); }
};
// 使用
auto req = HttpRequestBuilder()
.SetUrl("https://api.example.com")
.AddHeader("Auth", "token")
.SetBody("{}")
.Build();