首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 建造者模式深度解析:將複雜對象構建與表示分離

     編輯:關於C++

當對象構建過程極其複雜(如需分步驟、引入參數、不同表示)時,建造者模式 能將「構建邏輯」與「具體表示」解耦,讓相同構建流程產出不同產品。本文以「大學四年教育」為生活類比,配合 UML、完整代碼與對比工廠模式,徹底講透 Builder。

生活類比:大學教育即建造者

  • Director(指揮者):教務處,規定「大一、大二、大三、大四」四個階段(構建步驟固定)。
  • Builder(抽象建造者):專業培養方案,定義「修公共課、修專業課、做專題、實習」介面。
  • ConcreteBuilder(具體建造者):計算機系、外語系、藝術系……不同專業實現細節不同,產出不同「畢業生」。
  • Product(產品):畢業生,擁有「知識結構、技能證書、實習經歷」等屬性。

UML 結構

Builder模式UML

核心關係:

  1. Director 聚合 Builder*,透過多態呼叫 BuildPartA/B/C。
  2. Construct() 封裝固定構建順序。
  3. ConcreteBuilder 實現具體構建細節,持有 Product* 並最終 GetProduct()。

完整代碼實現

Builder.h

class Product {
    string m_partA, m_partB, m_partC;
public:
    void setPartA(const string& s) { m_partA = s; }
    void setPartB(const string& s) { m_partB = s; }
    void setPartC(const string& s) { m_partC = s; }
};

class Builder {
public:
    virtual void BuildPartA() = 0;
    virtual void BuildPartB() = 0;
    virtual void BuildPartC() = 0;
    virtual Product* GetProduct() = 0;
    virtual ~Builder() {}
};

class ConcreteBuilder1 : public Builder { /* 實現細節1 */ };
class ConcreteBuilder2 : public Builder { /* 實現細節2 */ };

class Director {
    Builder* m_pBuilder;
public:
    Director(Builder* b) : m_pBuilder(b) {}
    void Construct() { // 固定構建順序
        m_pBuilder->BuildPartA();
        m_pBuilder->BuildPartB();
        m_pBuilder->BuildPartC();
    }
    ~Director() { delete m_pBuilder; }
};

Director.cpp 關鍵實現

ConcreteBuilder1::ConcreteBuilder1() {
    m_pProduct = new Product();
    cout << "Create empty product!" << endl;
}
void ConcreteBuilder1::BuildPartA() { m_pProduct->setPartA("A"); cout << "BuildPartA" << endl; }
void ConcreteBuilder1::BuildPartB() { m_pProduct->setPartB("B"); cout << "BuildPartB" << endl; }
void ConcreteBuilder1::BuildPartC() { m_pProduct->setPartC("C"); cout << "BuildPartC" << endl; }
Product* ConcreteBuilder1::GetProduct() { return m_pProduct; }

main.cpp 測試

int main() {
    Director* d1 = new Director(new ConcreteBuilder1());
    d1->Construct(); // 輸出: Create empty product! BuildPartA BuildPartB BuildPartC
    Director* d2 = new Director(new ConcreteBuilder2());
    d2->Construct(); // 同樣流程,但細節不同
    return 0;
}

建造者 vs 工廠模式:核心差異

維度Builder 模式Factory 模式
關注點構建順序與細節創建對象本身
適用場景產品複雜、多步驟、參數化、不同表示產品相對簡單、一次性創建
返回時機構建完成後 GetProduct()創建即返回
耦合度Director 僅依賴 Builder 介面Client 直接依賴 Factory

何時使用 Builder?

  • 產品類極其複雜(如 HTTP 請求構建器、SQL 查詢構建器、文檔生成器)
  • 構建步驟順序固定,但每步實現細節多變
  • 需要將構建過程與最終表示分離,支援多種表示
  • 參數眾多且有預設值(可結合 Fluent Builder 鏈式調用)

現代 C++ 擴展:Fluent Builder

class HtmlBuilder {
    HtmlElement root;
public:
    HtmlBuilder(string name) : root(name) {}
    HtmlBuilder& addChild(string name, string text) {
        root.elements.emplace_back(name, text);
        return *this; // 支援鏈式
    }
    string str() { return root.str(); }
};
// 使用
HtmlBuilder builder("ul");
builder.addChild("li", "Item1").addChild("li", "Item2");
cout << builder.str();

這是 Builder 在現代 C++(如 std::optional、std::variant、Builder Pattern for Protobuf)中的常見演進形式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved