建造者模式是一種創建型設計模式,它將復雜對象的構建過程與表示分離,使得同樣的構建過程可以創建不同的表示。核心思想是指揮者定流程,建造者填細節,通過多個步驟逐步構建對象,并允許靈活組合這些步驟以生成不同配置的對象。通過將復雜對象的構建步驟抽象化,實現了"流程固定、配置可變"的靈活創建方式。
介紹
核心角色
- 產品(Product):被構建的復雜對象(如電腦、汽車)。
- 抽象建造者(Abstract Builder):定義構建產品的抽象方法(步驟)和返回產品的接口。
- 具體建造者(Concrete Builder):實現抽象建造者的方法,完成具體的構建步驟,并提供獲取產品的方式。
- 指揮者(Director):控制構建流程(調用建造者的步驟),隔離客戶端與構建過程。
優點
- 分離構建與表示:構建流程(指揮者)與具體部件配置(建造者)分離,便于擴展新產品。
- 靈活定制:通過更換具體建造者,可在不改變流程的情況下生成不同配置的對象。
- 精確控制構建過程:分步構建允許在每個步驟中加入校驗或邏輯,確保對象正確構建。
- 代碼復用:公共構建流程在指揮者中實現,避免重復編碼。
適用場景
- 構建復雜對象
當對象包含多個部件(如電腦、汽車、文檔),且構建步驟固定但部件配置可變時(如不同配置的電腦)。 - 需要多種表示形式
同一構建流程需生成不同產品(如同一文檔模板生成PDF、Word、HTML版本)。 - 構建過程需精細控制
需分步構建對象,或需要在構建過程中調整步驟(如先裝CPU再裝內存,順序不可亂)。
實現
以組裝電腦為例,電腦包含CPU、內存、顯卡等部件,用戶可定制不同配置(如辦公電腦、游戲電腦),適合用建造者模式分離"組裝流程"和"具體配置"。
#include <string>
#include <iostream>
#include <vector>// 產品:電腦
class Computer {
private:std::string cpu; // 處理器std::string memory; // 內存std::string graphics; // 顯卡std::string storage; // 存儲
public:void setCPU(const std::string& c) { cpu = c; }void setMemory(const std::string& m) { memory = m; }void setGraphics(const std::string& g) { graphics = g; }void setStorage(const std::string& s) { storage = s; }// 展示電腦配置void showInfo() const {std::cout << "CPU: " << cpu << "\n"<< "內存: " << memory << "\n"<< "顯卡: " << graphics << "\n"<< "存儲: " << storage << std::endl;}
};// 抽象建造者:定義電腦組裝步驟
class ComputerBuilder {
public:virtual ~ComputerBuilder() = default;virtual void buildCPU() = 0; // 構建CPUvirtual void buildMemory() = 0; // 構建內存virtual void buildGraphics() = 0; // 構建顯卡virtual void buildStorage() = 0; // 構建存儲virtual Computer* getResult() = 0; // 返回組裝好的電腦
};// 具體建造者1:辦公電腦
class OfficeComputerBuilder : public ComputerBuilder {
private:Computer* computer; // 正在構建的電腦
public:OfficeComputerBuilder() { computer = new Computer(); }~OfficeComputerBuilder() override { delete computer; }void buildCPU() override {computer->setCPU("Intel i5"); // 辦公級CPU}void buildMemory() override {computer->setMemory("16GB DDR4"); // 中等內存}void buildGraphics() override {computer->setGraphics("集成顯卡"); // 無需獨立顯卡}void buildStorage() override {computer->setStorage("512GB SSD"); // 夠用的存儲}Computer* getResult() override {return computer; // 返回構建好的電腦(轉移所有權)}
};// 具體建造者2:游戲電腦
class GameComputerBuilder : public ComputerBuilder {
private:Computer* computer;
public:GameComputerBuilder() { computer = new Computer(); }~GameComputerBuilder() override { delete computer; }void buildCPU() override {computer->setCPU("Intel i9"); // 高性能CPU}void buildMemory() override {computer->setMemory("32GB DDR5"); // 大容量高速內存}void buildGraphics() override {computer->setGraphics("NVIDIA RTX 4090"); // 頂級顯卡}void buildStorage() override {computer->setStorage("2TB SSD"); // 大容量存儲}Computer* getResult() override {return computer;}
};// 指揮者:控制構建流程
class Director {
private:ComputerBuilder* builder; // 指向當前建造者
public:explicit Director(ComputerBuilder* b) : builder(b) {}// 切換建造者void setBuilder(ComputerBuilder* b) {builder = b;}// 執行構建流程(固定步驟)Computer* construct() {builder->buildCPU();builder->buildMemory();builder->buildGraphics();builder->buildStorage();return builder->getResult(); // 返回最終產品}
};int main() {// 1. 創建具體建造者(辦公電腦)ComputerBuilder* officeBuilder = new OfficeComputerBuilder();Director director(officeBuilder); // 指揮者控制構建流程Computer* officePC = director.construct(); // 執行構建std::cout << "=== 辦公電腦配置 ===" << std::endl;officePC->showInfo();// 2. 創建具體建造者(游戲電腦)ComputerBuilder* gameBuilder = new GameComputerBuilder();director.setBuilder(gameBuilder); // 切換建造者Computer* gamePC = director.construct();std::cout << "\n=== 游戲電腦配置 ===" << std::endl;gamePC->showInfo();// 清理資源delete officePC;delete gamePC;delete officeBuilder;delete gameBuilder;return 0;
}
輸出結果
=== 辦公電腦配置 ===
CPU: Intel i5
內存: 16GB DDR4
顯卡: 集成顯卡
存儲: 512GB SSD=== 游戲電腦配置 ===
CPU: Intel i9
內存: 32GB DDR5
顯卡: NVIDIA RTX 4090
存儲: 2TB SSD
應用場景
- 產品配置
- 電子產品組裝(如電腦、手機的不同型號配置)。
- 汽車制造(同一車型的標準版、豪華版、運動版)。
- 文檔生成
- 報告生成工具(同一內容生成PDF、Markdown、HTML格式)。
- 代碼生成器(根據模板生成不同語言的代碼)。
- 復雜對象創建
- 游戲角色創建(同一角色模型,不同裝備、技能配置)。
- 數據庫連接池(不同參數配置的連接對象)。
- 框架與庫
- C++ STL中的
stringstream
(分步構建字符串)。 - 建造者模式在JSON/XML解析器中用于構建樹形結構。
- C++ STL中的
優化
優化方向
- 支持動態自定義配置:允許客戶端靈活設置每個部件(而非局限于預設的“辦公/游戲”配置)。
- 引入可選部件與校驗:支持非必需部件(如散熱器、聲卡),并添加部件兼容性校驗。
- 使用智能指針管理資源:避免手動內存管理,防止內存泄漏。
- 流暢接口(Fluent Interface):通過鏈式調用簡化建造過程,提升代碼可讀性。
- 指揮者功能增強:支持自定義構建流程(如可選步驟、步驟順序調整)。
#include <string>
#include <iostream>
#include <vector>
#include <memory> // 智能指針
#include <stdexcept> // 異常處理// 產品:電腦(支持更多部件和兼容性校驗)
class Computer {
private:std::string cpu;std::string memory;std::string graphics; // 可選:集成/獨立顯卡std::string storage;std::string cooler; // 可選:散熱器std::vector<std::string> compatibleCPUs = {"Intel i5", "Intel i9", "AMD Ryzen 5"};std::vector<std::string> compatibleMemories = {"16GB DDR4", "32GB DDR5", "64GB DDR5"};public:// 鏈式設置方法(Fluent Interface)Computer& setCPU(const std::string& c) { // 校驗CPU兼容性if (std::find(compatibleCPUs.begin(), compatibleCPUs.end(), c) == compatibleCPUs.end()) {throw std::invalid_argument("不支持的CPU型號:" + c);}cpu = c; return *this; }Computer& setMemory(const std::string& m) { if (std::find(compatibleMemories.begin(), compatibleMemories.end(), m) == compatibleMemories.end()) {throw std::invalid_argument("不支持的內存型號:" + m);}memory = m; return *this; }Computer& setGraphics(const std::string& g) { graphics = g; return *this; }Computer& setStorage(const std::string& s) { storage = s; return *this; }Computer& setCooler(const std::string& c) { cooler = c; return *this; }// 展示配置(包含可選部件)void showInfo() const {std::cout << "CPU: " << cpu << "\n"<< "內存: " << memory << "\n"<< "顯卡: " << (graphics.empty() ? "無(集成)" : graphics) << "\n"<< "存儲: " << storage << "\n"<< "散熱器: " << (cooler.empty() ? "無(默認)" : cooler) << std::endl;}// 校驗必填部件是否齊全bool isValid() const {return !cpu.empty() && !memory.empty() && !storage.empty();}
};// 抽象建造者(支持鏈式調用和智能指針)
class ComputerBuilder {
public:using Ptr = std::unique_ptr<ComputerBuilder>; // 智能指針管理virtual ~ComputerBuilder() = default;// 純虛方法:構建步驟(支持鏈式返回)virtual ComputerBuilder& buildCPU() = 0;virtual ComputerBuilder& buildMemory() = 0;virtual ComputerBuilder& buildGraphics() { return *this; } // 可選步驟(默認空實現)virtual ComputerBuilder& buildStorage() = 0;virtual ComputerBuilder& buildCooler() { return *this; } // 可選步驟// 返回產品(智能指針,自動釋放)virtual std::unique_ptr<Computer> getResult() {if (!computer->isValid()) {throw std::logic_error("電腦配置不完整,缺少必填部件");}return std::move(computer); // 轉移所有權}protected:std::unique_ptr<Computer> computer = std::make_unique<Computer>(); // 產品
};// 具體建造者1:辦公電腦(基礎配置,可選散熱器)
class OfficeComputerBuilder : public ComputerBuilder {
public:ComputerBuilder& buildCPU() override {computer->setCPU("Intel i5");return *this;}ComputerBuilder& buildMemory() override {computer->setMemory("16GB DDR4");return *this;}// 辦公電腦默認無獨立顯卡(使用集成),無需重寫buildGraphicsComputerBuilder& buildStorage() override {computer->setStorage("512GB SSD");return *this;}// 可選:為辦公電腦添加低端散熱器ComputerBuilder& buildCooler() override {computer->setCooler("基礎風冷散熱器");return *this;}
};// 具體建造者2:游戲電腦(高性能配置,強制獨立顯卡和散熱器)
class GameComputerBuilder : public ComputerBuilder {
public:ComputerBuilder& buildCPU() override {computer->setCPU("Intel i9");return *this;}ComputerBuilder& buildMemory() override {computer->setMemory("32GB DDR5");return *this;}// 游戲電腦必須有獨立顯卡(重寫為強制步驟)ComputerBuilder& buildGraphics() override {computer->setGraphics("NVIDIA RTX 4090");return *this;}ComputerBuilder& buildStorage() override {computer->setStorage("2TB SSD");return *this;}// 游戲電腦必須有高性能散熱器ComputerBuilder& buildCooler() override {computer->setCooler("水冷散熱器");return *this;}
};// 具體建造者3:自定義建造者(允許客戶端自由配置)
class CustomComputerBuilder : public ComputerBuilder {
public:// 空實現,由客戶端手動調用產品的set方法配置ComputerBuilder& buildCPU() override { return *this; }ComputerBuilder& buildMemory() override { return *this; }ComputerBuilder& buildStorage() override { return *this; }// 提供直接訪問產品的接口(用于自定義配置)Computer* getComputer() { return computer.get(); }
};// 指揮者(支持靈活流程和可選步驟)
class Director {
public:// 構建基礎電腦(必填部件:CPU、內存、存儲)std::unique_ptr<Computer> buildBasic(ComputerBuilder::Ptr builder) {builder->buildCPU()->buildMemory()->buildStorage();return builder->getResult();}// 構建完整電腦(包含可選部件)std::unique_ptr<Computer> buildFull(ComputerBuilder::Ptr builder) {builder->buildCPU()->buildMemory()->buildGraphics()->buildStorage()->buildCooler();return builder->getResult();}// 自定義流程(按傳入的步驟函數執行)using StepFunc = std::function<void(ComputerBuilder*)>;std::unique_ptr<Computer> buildCustom(ComputerBuilder::Ptr builder, const std::vector<StepFunc>& steps) {for (const auto& step : steps) {step(builder.get());}return builder->getResult();}
};int main() {try {Director director;// 1. 構建辦公電腦(基礎配置)std::cout << "=== 辦公電腦(基礎配置) ===" << std::endl;auto officeBasic = director.buildBasic(std::make_unique<OfficeComputerBuilder>());officeBasic->showInfo();// 2. 構建游戲電腦(完整配置)std::cout << "\n=== 游戲電腦(完整配置) ===" << std::endl;auto gameFull = director.buildFull(std::make_unique<GameComputerBuilder>());gameFull->showInfo();// 3. 自定義電腦(自由配置部件)std::cout << "\n=== 自定義電腦 ===" << std::endl;auto customBuilder = std::make_unique<CustomComputerBuilder>();// 直接配置產品的具體部件(鏈式調用)customBuilder->getComputer()->setCPU("AMD Ryzen 5")->setMemory("64GB DDR5")->setGraphics("AMD Radeon RX 7900")->setStorage("4TB SSD")->setCooler("高端風冷散熱器");// 用指揮者構建(此處僅做校驗)auto customPC = director.buildBasic(std::move(customBuilder));customPC->showInfo();// 4. 自定義構建流程(動態指定步驟)std::cout << "\n=== 動態流程構建(僅CPU+內存+存儲) ===" << std::endl;auto dynamicBuilder = std::make_unique<CustomComputerBuilder>();dynamicBuilder->getComputer()->setCPU("Intel i5")->setMemory("32GB DDR4")->setStorage("1TB SSD");// 定義自定義步驟(僅執行CPU和內存校驗)std::vector<Director::StepFunc> steps = {[](ComputerBuilder* b) { b->buildCPU(); }, // 實際是校驗CPU已設置[](ComputerBuilder* b) { b->buildMemory(); } // 校驗內存已設置};auto dynamicPC = director.buildCustom(std::move(dynamicBuilder), steps);dynamicPC->showInfo();} catch (const std::exception& e) {std::cerr << "錯誤:" << e.what() << std::endl;return 1;}return 0;
}
輸出結果
=== 辦公電腦(基礎配置) ===
CPU: Intel i5
內存: 16GB DDR4
顯卡: 無(集成)
存儲: 512GB SSD
散熱器: 無(默認)=== 游戲電腦(完整配置) ===
CPU: Intel i9
內存: 32GB DDR5
顯卡: NVIDIA RTX 4090
存儲: 2TB SSD
散熱器: 水冷散熱器=== 自定義電腦 ===
CPU: AMD Ryzen 5
內存: 64GB DDR5
顯卡: AMD Radeon RX 7900
存儲: 4TB SSD
散熱器: 高端風冷散熱器=== 動態流程構建(僅CPU+內存+存儲) ===
CPU: Intel i5
內存: 32GB DDR4
顯卡: 無(集成)
存儲: 1TB SSD
散熱器: 無(默認)
優化點說明
- 動態自定義配置
- 新增
CustomComputerBuilder
,允許客戶端通過getComputer()
直接訪問產品,自由設置部件(如setCPU("AMD Ryzen 5")
),突破預設配置的限制。 - 配合鏈式調用(
obj->setA()->setB()
),使配置代碼更簡潔直觀。
- 新增
- 可選部件與校驗機制
- 將顯卡、散熱器設為可選部件,抽象建造者中提供默認空實現,具體建造者按需重寫(如游戲電腦必須實現
buildGraphics
)。 - 產品內部添加兼容性校驗(如
compatibleCPUs
)和完整性校驗(isValid()
),避免無效配置(如使用不支持的CPU型號)。
- 將顯卡、散熱器設為可選部件,抽象建造者中提供默認空實現,具體建造者按需重寫(如游戲電腦必須實現
- 智能指針與資源安全
- 使用
std::unique_ptr
管理建造者和產品的生命周期,無需手動delete
,徹底避免內存泄漏。 - 產品所有權通過
std::move
轉移,明確資源歸屬。
- 使用
- 指揮者功能增強
- 提供多種預設流程(
buildBasic
基礎配置、buildFull
完整配置),滿足不同場景需求。 - 支持自定義流程(
buildCustom
),通過函數對象動態指定步驟,靈活度極高(如僅構建CPU+內存+存儲)。
- 提供多種預設流程(
- 擴展性提升
- 新增部件(如未來添加“聲卡”)時,只需在
Computer
中添加setSoundCard
方法,抽象建造者中添加默認空實現,無需修改現有建造者和指揮者,符合開閉原則。
- 新增部件(如未來添加“聲卡”)時,只需在
優點
- 更高的靈活性:支持預設配置、完全自定義配置、動態流程配置,適應多樣化需求。
- 更強的安全性:智能指針自動管理內存,校驗機制避免無效配置,異常處理明確錯誤原因。
- 更好的擴展性:新增部件或流程時,對現有代碼侵入性極小,易于維護。
- 更優的易用性:鏈式調用和多樣化構建接口降低使用門檻,客戶端可按需選擇復雜度。
適用場景
- 復雜產品定制平臺:如電商網站的“自定義PC”功能,用戶可自由選擇每個部件,系統自動校驗兼容性。
- 動態報表生成:允許用戶選擇報表包含的模塊(表格、圖表、摘要),按自定義順序組裝。
- 游戲角色創建器:玩家可選擇角色的種族、職業、技能、裝備,系統確保選擇組合有效(如某些技能僅特定種族可用)。