設計模式九:構建器模式 (Builder Pattern)

?動機(Motivation)

?1、在軟件系統中,有時候面臨著“一個復雜對象”的創建工作,其通常由各個部分的子對象用一定的算法構成;由于需求的變化,這個復雜對象的各個部分經常面臨著劇烈的變化,但是將它們組合在一起的算法卻相對穩定。
2、如何應對這種變化?如何提供一種“封裝機制”來隔離出“復雜對象的各個部分”的變化,從而保持系統中的“穩定構建算法”不隨著需求改變而改變?

?基本概念

定義:構建器模式是一種創建型設計模式,它允許您分步驟創建復雜對象,使得相同的構建過程可以創建不同的表示。

構建器模式的核心思想是將復雜對象的構建與其表示分離,使得:

  • 客戶端不需要知道對象內部的具體組成細節

  • 相同的構建過程可以創建不同的表示

  • 可以更精細地控制對象的構建過程

實現方式

1. 經典構建器模式實現

#include <iostream>
#include <memory>
#include <string>// 最終要構建的產品
class Pizza {
public:void setDough(const std::string& dough) {dough_ = dough;}void setSauce(const std::string& sauce) {sauce_ = sauce;}void setTopping(const std::string& topping) {topping_ = topping;}void showPizza() const {std::cout << "Pizza with " << dough_ << " dough, "<< sauce_ << " sauce and "<< topping_ << " topping." << std::endl;}private:std::string dough_;std::string sauce_;std::string topping_;
};// 抽象構建器
class PizzaBuilder {
public:virtual ~PizzaBuilder() = default;Pizza* getPizza() {return pizza_.get();}void createNewPizza() {pizza_ = std::make_unique<Pizza>();}virtual void buildDough() = 0;virtual void buildSauce() = 0;virtual void buildTopping() = 0;protected:std::unique_ptr<Pizza> pizza_;
};// 具體構建器 -  HawaiianPizzaBuilder
class HawaiianPizzaBuilder : public PizzaBuilder {
public:void buildDough() override {pizza_->setDough("cross");}void buildSauce() override {pizza_->setSauce("mild");}void buildTopping() override {pizza_->setTopping("ham+pineapple");}
};// 具體構建器 - SpicyPizzaBuilder
class SpicyPizzaBuilder : public PizzaBuilder {
public:void buildDough() override {pizza_->setDough("pan baked");}void buildSauce() override {pizza_->setSauce("hot");}void buildTopping() override {pizza_->setTopping("pepperoni+salami");}
};// 指導者 (Director) - 控制構建過程
class Cook {
public:void setPizzaBuilder(PizzaBuilder* pb) {pizzaBuilder_ = pb;}Pizza* getPizza() {return pizzaBuilder_->getPizza();}void constructPizza() {pizzaBuilder_->createNewPizza();pizzaBuilder_->buildDough();pizzaBuilder_->buildSauce();pizzaBuilder_->buildTopping();}private:PizzaBuilder* pizzaBuilder_;
};int main() {Cook cook;// 構建 Hawaiian PizzaHawaiianPizzaBuilder hawaiianBuilder;cook.setPizzaBuilder(&hawaiianBuilder);cook.constructPizza();Pizza* hawaiianPizza = cook.getPizza();hawaiianPizza->showPizza();  // 輸出: Pizza with cross dough, mild sauce and ham+pineapple topping.// 構建 Spicy PizzaSpicyPizzaBuilder spicyBuilder;cook.setPizzaBuilder(&spicyBuilder);cook.constructPizza();Pizza* spicyPizza = cook.getPizza();spicyPizza->showPizza();  // 輸出: Pizza with pan baked dough, hot sauce and pepperoni+salami topping.return 0;
}

2. 流式接口構建器 (更現代的C++實現)

#include <iostream>
#include <memory>
#include <string>class Computer {
public:void setCPU(const std::string& cpu) { cpu_ = cpu; }void setRAM(const std::string& ram) { ram_ = ram; }void setStorage(const std::string& storage) { storage_ = storage; }void setGPU(const std::string& gpu) { gpu_ = gpu; }void showSpecs() const {std::cout << "Computer Specs:\n"<< "CPU: " << cpu_ << "\n"<< "RAM: " << ram_ << "\n"<< "Storage: " << storage_ << "\n"<< "GPU: " << (gpu_.empty() ? "Integrated" : gpu_) << "\n";}private:std::string cpu_;std::string ram_;std::string storage_;std::string gpu_;
};class ComputerBuilder {
public:ComputerBuilder() : computer_(std::make_unique<Computer>()) {}ComputerBuilder& setCPU(const std::string& cpu) {computer_->setCPU(cpu);return *this;}ComputerBuilder& setRAM(const std::string& ram) {computer_->setRAM(ram);return *this;}ComputerBuilder& setStorage(const std::string& storage) {computer_->setStorage(storage);return *this;}ComputerBuilder& setGPU(const std::string& gpu) {computer_->setGPU(gpu);return *this;}std::unique_ptr<Computer> build() {return std::move(computer_);}private:std::unique_ptr<Computer> computer_;
};int main() {// 使用流式接口構建計算機auto gamingPC = ComputerBuilder().setCPU("Intel i9-13900K").setRAM("32GB DDR5").setStorage("2TB NVMe SSD").setGPU("NVIDIA RTX 4090").build();gamingPC->showSpecs();auto officePC = ComputerBuilder().setCPU("AMD Ryzen 5").setRAM("16GB DDR4").setStorage("512GB SSD").build();  // 沒有設置GPUofficePC->showSpecs();return 0;
}

?UML結構

?

構建器模式的優點

  1. 分步構建:可以分步驟構建復雜對象

  2. 復用構建過程:相同的構建過程可以創建不同的產品

  3. 單一職責原則:將復雜對象的構建代碼與其業務邏輯分離

  4. 更好的控制:對構建過程有更精細的控制

  5. 可擴展性:添加新的具體構建器無需修改現有代碼

適用場景

  1. 當創建復雜對象的算法應該獨立于該對象的組成部分及其裝配方式時

  2. 當構造過程必須允許被構造的對象有不同的表示時

  3. 當需要避免"伸縮構造函數"問題(構造函數參數過多)時

  4. 當對象有大量可選組件或配置時

構建器模式的變體

  1. 流式接口構建器:通過方法鏈提供更優雅的API

  2. Groovy風格構建器:利用C++運算符重載實現更自然的語法

  3. 組合構建器:多個構建器協同工作構建復雜對象

注意事項

  1. 構建器模式會增加代碼復雜度,因為需要創建多個新類

  2. 對于簡單對象,直接使用構造函數可能更合適

  3. 確保構建器在構建完成后不能被重復使用(除非顯式重置)

構建器模式在C++中特別適合用于創建配置復雜的對象,特別是當對象有許多可選組件時。流式接口的實現方式使得代碼更加清晰易讀。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90315.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90315.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90315.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何高效合并音視頻文件

在自我學習或者進行視頻剪輯的時候&#xff0c;經常從資源網址下載音視頻分離的文件&#xff0c;例如audio_file1.m4a和video_1.mp4&#xff0c;之后需要把這兩個文件合并在一起。于是條件反射得想要利用剪映等第三方工具&#xff0c;進行音視頻的封裝。可惜不幸的是&#xff0…

虛幻 5 與 3D 軟件的協作:實時渲染,所見所得

《曼達洛人》的星際飛船在片場實時掠過虛擬荒漠&#xff0c;游戲開發者拖動滑塊就能即時看到角色皮膚的通透變化&#xff0c;實時渲染技術正以 “所見即所得” 的核心優勢&#xff0c;重塑著 3D 創作的整個邏輯。虛幻引擎 5&#xff08;UE5&#xff09;憑借 Lumen 全局光照和 N…

?Eyeriss 架構中的訪存行為解析(騰訊元寶)

?Eyeriss 架構中的訪存行為解析?Eyeriss 是 MIT 提出的面向卷積神經網絡&#xff08;CNN&#xff09;的能效型 NPU&#xff08;神經網絡處理器&#xff09;架構&#xff0c;其核心創新在于通過硬件結構優化訪存行為&#xff0c;以解決傳統 GPU 在處理 CNN 時因數據搬運導致的…

數字圖像處理(三:圖像如果當作矩陣,那加減乘除處理了矩陣,那圖像咋變):從LED冬奧會、奧運會及春晚等等大屏,到手機小屏,快來挖一挖里面都有什么

數字圖像處理&#xff08;三&#xff09;一、&#xff08;準備工作&#xff1a;咋玩&#xff0c;用什么玩具&#xff09;圖像以矩陣形式存儲&#xff0c;那矩陣一變、圖像立刻跟著變&#xff1f;1. Python Jupyter Notebook/Lab 庫 (NumPy, OpenCV, Matplotlib, scikit-image…

docker-desktop啟動失敗

報錯提示deploying WSL2 distributions ensuring main distro is deployed: checking if main distro is up to date: checking main distro bootstrap version: getting main distro bootstrap version: open \\wsl$\docker-desktop\etc\wsl_bootstrap_version: The network n…

基于FastMCP創建MCP服務器的小白級教程

以下是基于windows 11操作系統環境的開發步驟。 1、python環境搭建 訪問官網&#xff1a;https://www.python.org/。下載相應的版本&#xff08;如&#xff1a;3.13.5&#xff09;&#xff0c;然后安裝。 安裝完成之后&#xff0c;使用命令行工具輸入python&#xff0c;顯示…

網絡協議與層次對應表

網絡協議與層次對應表&#xff08;OSI & TCP/IP模型&#xff09;OSI七層模型TCP/IP四層模型協議/技術核心功能與應用?應用層?應用層HTTP/HTTPS網頁傳輸協議&#xff08;HTTP&#xff09;及其加密版&#xff08;HTTPS&#xff09;FTP文件上傳/下載協議SMTP/POP3/IMAPSMTP發…

android studio(NewsApiDemo)100%kotlin

api接口地址&#xff1a;https://newsapi.org/docs/get-started 項目成品地址&#xff1a;https://github.com/RushHan824/NewsApiDemo 項目效果展示&#xff1a; MVVM數據流 UML圖 本系列文章將帶你從零實現一個新聞列表App&#xff0c;適合零基礎讀者。一步步來&#xff0c…

面試高頻題 力扣 417. 太平洋大西洋水流問題 洪水灌溉(FloodFill) 深度優先遍歷(dfs) 暴力搜索 C++解題思路 每日一題

目錄零、題目描述&#xff1a;用人話再講一遍一、為什么這道題值得咱們學習&#xff1f;二、思路探索常規思路&#xff1a;逐個檢查每個格子&#xff08;會超時&#xff01;??&#xff09;三、正難則反&#xff1a;反向思維的巧妙應用 &#x1f504;&#xff08;思考時間&…

博物館智慧導覽系統AR交互與自動感應技術:從虛實融合到智能講解的技術實踐

本文面向博物館信息化開發者、智慧場館系統技術建設師及AR 設計工程師,從AR 交互與自動感應技術的邏輯出發,拆解AR虛實融合技術與智能講解自動感應技術的原理&#xff0c;為相關開發者實踐提供可復用的技術路徑。如需獲取博物館智慧導覽系統解決方案請前往文章最下方獲取&#…

高效編程革命:DeepSeek V3多語言支持與性能優化實戰

文章目錄 如何利用DeepSeek V3編寫高效程序代碼:從原理到實踐 引言 一、DeepSeek V3核心能力解析 1.1 模型架構與優勢 1.2 與傳統編程輔助工具對比 二、高效代碼編寫實踐指南 2.1 精準提示工程(Prompt Engineering) 基礎提示模板 高級提示技巧 2.2 生產級代碼生成案例 示例:…

OkHttp 與 JSON 解析庫完美結合:Moshi/Jackson/Gson 實戰指南

前言在現代 Android 開發中&#xff0c;網絡請求與 JSON 數據處理是密不可分的。OkHttp 作為強大的 HTTP 客戶端&#xff0c;與 JSON 解析庫&#xff08;Moshi/Jackson/Gson&#xff09;的結合使用&#xff0c;可以極大簡化網絡請求與數據解析的流程。本文將詳細介紹如何將 OkH…

An error occurred at line: 1 in the generated java file問題處理及tomcat指定對應的jdk運行

一、背景 tomcat7啟動后&#xff0c;加載jsp頁面報錯&#xff0c;提示無法將jsp編譯為class文件&#xff0c;主要報錯信息如下&#xff1a; An error occurred at line: 1 in the generated java file 最后確認該錯誤原因為&#xff1a;tomcat7不支持jdk1.8版本 機器上已配…

深入剖析大模型在文本生成式 AI 產品架構中的核心地位

一、大模型的崛起與概念解析 在人工智能技術飛速迭代的當下&#xff0c;大模型已成為驅動行業發展的核心引擎。從技術定義來看&#xff0c;大模型&#xff08;Large Model&#xff09; 是指基于深度學習架構、具備海量參數規模&#xff08;通常數十億至數萬億級別&#xff09;&…

Vue Scoped樣式:當動態元素成為“無家可歸“的孤兒

引言&#xff1a;一場CSS的"身份危機"想象一下&#xff1a;你精心設計了一個Vue組件&#xff0c;為每個元素添加了漂亮的樣式。你滿意地添加了scoped屬性&#xff0c;確保樣式不會"越獄"影響其他組件。然后你動態添加了一些新元素&#xff0c;卻發現它們完…

vmware分配了ubuntu空間但是ubuntu沒有獲取

一開始我看vmware中的ubuntu磁盤空間只有200g不夠用&#xff0c;我在vmware給Ubuntu分了300G的磁盤空間&#xff0c;但是ubuntu還是只有之前的200g 如圖在ubuntu查看后來發現&#xff0c;在磁盤軟件里面需要自己分配磁盤空間大小拓展后就可以了

[MarkdownGithub] 使用塊引用高亮顯示“注意“和“警告“和其他注意方式的選項

參考來源: https://github.com/orgs/community/discussions/16925 Alerts are an extension of Markdown used to emphasize critical information. On GitHub, they are displayed with distinctive colors and icons to indicate the importance of the content. 提示框是 Ma…

mac測試ollama llamaindex

LlamaIndexs 將大語言模型和外部數據連接在一起的工具。大模型prompt有一個長度限制&#xff0c;當外部知識的內容超過這個長度&#xff0c;無法同時將有效信息傳遞給大模型&#xff0c;因此就誕生了 LlamaIndex。 具體操作就是通過多輪對話的方式不斷提純外部數據&#xff0c…

數據結構:字符串:大小寫轉換(changing case of a string)

目錄 第一性問題&#xff1a;什么是“大小寫”&#xff1f; 逐步構造代碼&#xff1a;全部轉為大寫 我們現在用 第一性原理 的方式&#xff0c;從字符串與字符的本質出發&#xff0c;一步步推導出如何在 C 語言中將字符串中的字母變成全部大寫或全部小寫。 第一性問題&…

閑庭信步使用圖像驗證平臺加速FPGA的開發:第三十二課——車牌識別的FPGA實現(4)車牌字符的分割定位

&#xff08;本系列只需要modelsim即可完成數字圖像的處理&#xff0c;每個工程都搭建了全自動化的仿真環境&#xff0c;只需要雙擊top_tb.bat文件就可以完成整個的仿真&#xff0c;大大降低了初學者的門檻&#xff01;&#xff01;&#xff01;&#xff01;如需要該系列的工程…