設計模式-建造者模式(Builder Pattern)

一、建造者模式說明

????????建造者模式(Builder Pattern)是一種創建型設計模式,它的主要目的是將一個復雜對象的構建過程與其表示分離,使得同樣的構建過程可以創建不同的表示。

在建造者模式中,通常涉及以下幾個角色:

產品(Product)

  • 產品是要構建的復雜對象,包含多個部件。
  • 產品通常是由多個部件組成的復雜對象,建造者模式的目標就是創建這個復雜對象。

抽象建造者(Builder)

  • 抽象建造者定義了創建產品各個部件的抽象接口。
  • 抽象建造者中通常包含多個方法,用于構建產品的各個部件,例如構建引擎、構建輪胎、構建座椅等。
  • 它可以是一個抽象類或接口。

具體建造者(Concrete Builder)

  • 具體建造者實現了抽象建造者接口,負責具體構建產品的各個部件。
  • 每個具體建造者類對應一個特定的產品類型,并定義了具體構建該產品的過程。
  • 具體建造者類通常包含私有成員變量用于保存構建過程中的臨時狀態,并提供方法來構建不同部件。

指揮者(Director)

  • 指揮者負責調用具體建造者的方法來構建產品。
  • 指揮者知道構建產品的具體步驟和順序,但不知道產品的具體細節。
  • 指揮者根據客戶端的需求調用具體建造者的方法,將產品的構建過程與表示分離。

二、建造者模式樣例

#include <iostream>
#include <string>// 產品類
class Product {
public:void setPartA(const std::string& partA) {partA_ = partA;}void setPartB(const std::string& partB) {partB_ = partB;}void setPartC(const std::string& partC) {partC_ = partC;}void show() const {std::cout << "Product parts: " << partA_ << ", " << partB_ << ", " << partC_ << std::endl;}private:std::string partA_;std::string partB_;std::string partC_;
};// 抽象建造者類
class Builder {
public:virtual ~Builder() {}virtual void buildPartA() = 0;virtual void buildPartB() = 0;virtual void buildPartC() = 0;virtual Product getResult() = 0;
};// 具體建造者類A
class ConcreteBuilderA : public Builder {
public:void buildPartA() override {product_.setPartA("PartA by ConcreteBuilderA");}void buildPartB() override {product_.setPartB("PartB by ConcreteBuilderA");}void buildPartC() override {product_.setPartC("PartC by ConcreteBuilderA");}Product getResult() override {return product_;}private:Product product_;
};// 具體建造者類B
class ConcreteBuilderB : public Builder {
public:void buildPartA() override {product_.setPartA("PartA by ConcreteBuilderB");}void buildPartB() override {product_.setPartB("PartB by ConcreteBuilderB");}void buildPartC() override {product_.setPartC("PartC by ConcreteBuilderB");}Product getResult() override {return product_;}private:Product product_;
};// 指揮者類
class Director {
public:void construct(Builder& builder) {builder.buildPartA();builder.buildPartB();builder.buildPartC();}
};int main() {Director director;ConcreteBuilderA builderA;ConcreteBuilderB builderB;// 構建產品Astd::cout << "Product A:" << std::endl;director.construct(builderA);Product productA = builderA.getResult();productA.show();// 構建產品Bstd::cout << "\nProduct B:" << std::endl;director.construct(builderB);Product productB = builderB.getResult();productB.show();return 0;
}

三、建造者模式的場景

以下是一些適用建造者模式的具體場景:

????????游戲角色創建器:在游戲中,玩家可以選擇不同的角色并自定義其外觀、能力和裝備。建造者模式可以用于創建角色的建造器,每個具體建造者負責構建不同類型的角色,而指揮者負責組裝角色的各個部件,最終創建出完整的角色對象。

????????文檔生成器:在文檔生成器中,可能需要創建不同類型的文檔,例如簡歷、報告、新聞稿等。建造者模式可以用于創建文檔的建造器,每個具體建造者負責構建不同類型的文檔,而指揮者負責組裝文檔的各個部件,最終生成所需的文檔對象。

????????電腦組裝器:在電腦組裝器中,用戶可以選擇不同的硬件配置和外設,并自定義其性能和功能。建造者模式可以用于創建電腦的建造器,每個具體建造者負責構建不同配置的電腦,而指揮者負責組裝電腦的各個部件,最終組裝成用戶所需的電腦。

????????汽車定制器:在汽車定制器中,用戶可以選擇不同的汽車型號、顏色、配置和附件。建造者模式可以用于創建汽車的建造器,每個具體建造者負責構建不同配置的汽車,而指揮者負責組裝汽車的各個部件,最終定制成用戶所需的汽車。

????????食品套餐訂購系統:在食品套餐訂購系統中,用戶可以選擇不同的食品套餐、主食、配菜和飲料。建造者模式可以用于創建食品套餐的建造器,每個具體建造者負責構建不同套餐的各個部件,而指揮者負責組裝套餐的各個部件,最終生成用戶所需的套餐對象。

四、建造者模式優缺點

建造者模式具有以下優點和缺點:

優點:

????????分離構建過程和表示:建造者模式將一個復雜對象的構建過程與其表示分離,使得同樣的構建過程可以創建不同的表示,提高了系統的靈活性。

????????隱藏構建細節:建造者模式將對象的構建過程封裝起來,只向客戶端暴露一個簡單的構建接口,客戶端不需要關心對象的構建細節,降低了客戶端與具體構建過程的耦合度。

????????更加精細地控制構建過程:建造者模式可以讓客戶端按照需要靈活地指定構建順序和選擇構建部件,可以更加精細地控制對象的構建過程,滿足不同的需求。

????????增加對象的可復用性:由于建造者模式將對象的構建過程封裝起來,可以在不改變原有代碼的情況下,通過新增具體建造者類來創建新的對象表示,提高了對象的可復用性。

????????增加系統的擴展性:由于建造者模式將構建過程和表示分離,新增具體建造者類或修改指揮者類不會影響其他部分的代碼,增加了系統的擴展性。

缺點:

????????增加系統復雜度:建造者模式引入了多個角色和類,增加了系統的復雜度,可能會導致代碼量增加,不利于理解和維護。

????????不適用于對象較簡單的情況:當對象的構建過程比較簡單,或者對象的內部結構比較穩定時,使用建造者模式可能會顯得繁瑣,不適合使用。

????????不利于組裝順序的靈活性:建造者模式將構建過程固化在建造者類中,可能會限制對象組裝順序的靈活性,如果需要改變組裝順序,則需要修改建造者類或指揮者類。

????????可能會產生多余的對象:由于建造者模式將構建過程和表示分離,可能會導致在構建對象過程中產生多余的對象,增加了系統的資源消耗。

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

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

相關文章

多業務場景下對于redis分布式鎖的一些思考

現在讓你寫一個Redis分布式鎖 大概率你會先寫一個框架 public Boolean setIfAbsent(String key, Object value,Long timeout) {try {return Boolean.TRUE.equals(objectRedisTemplate.opsForValue().setIfAbsent(key, value,timeout,TimeUnit.SECONDS));} catch (Exception e) …

2024開年,手機廠商革了自己的命

文&#xff5c;劉俊宏 編&#xff5c;王一粟 2024開年&#xff0c;AI終端的號角已經由手機行業吹響。 OPPO春節期間就沒閑著&#xff0c;首席產品官劉作虎在大年三十就迫不及待地宣布&#xff0c;OPPO正式進入AI手機時代。隨后在開年后就緊急召開了AI戰略發布會&#xff0c;…

【Antd】Form 表單獲取不到 Input 的值

文章目錄 今天遇到了一個奇怪的bug&#xff0c;Form表單中的Input組件的值&#xff0c;不能被Form獲取&#xff0c;導致輸入了內容&#xff0c;但是表單提交的時候值為undefined 報錯代碼 import { Button, Form, Input } from antd; import React from react;const App: Rea…

GaussDB SQL調優:建立合適的索引

背景 GaussDB是華為公司傾力打造的自研企業級分布式關系型數據庫&#xff0c;該產品具備企業級復雜事務混合負載能力&#xff0c;同時支持優異的分布式事務&#xff0c;同城跨AZ部署&#xff0c;數據0丟失&#xff0c;支持1000擴展能力&#xff0c;PB級海量存儲等企業級數據庫…

SQL中為什么不要使用1=1

最近看幾個老項目的SQL條件中使用了11&#xff0c;想想自己也曾經這樣寫過&#xff0c;略有感觸&#xff0c;特別拿出來說道說道。 編寫SQL語句就像炒菜&#xff0c;每一種調料的使用都可能會影響菜品的最終味道&#xff0c;每一個SQL條件的加入也可能會影響查詢的執行效率。那…

昨天Google發布了最新的開源模型Gemma,今天我來體驗一下

前言 看看以前寫的文章&#xff0c;業余搞人工智能還是很早之前的事情了&#xff0c;之前為了高工資&#xff0c;一直想從事人工智能相關的工作都沒有實現。現在終于可以安靜地系統地學習一下了。也是一邊學習一邊寫博客記錄吧。 昨天Google發布了最新的開源模型Gemma&#xf…

電商數據采集的幾個標準

面對體量巨大的電商數據&#xff0c;很多品牌會選擇對自己有用的數據進行分析&#xff0c;比如在控價過程中&#xff0c;需要對商品的價格數據進行監測&#xff0c;或者是需要做數據分析時&#xff0c;則需要采集到商品的價格、銷量、評價量、標題、店鋪名等信息&#xff0c;數…

Unity中.Net與Mono的關系

什么是.NET .NET是一個開發框架&#xff0c;它遵循并采用CIL(Common Intermediate Language)和CLR(Common Language Runtime)兩種約定&#xff0c; CIL標準為一種編譯標準&#xff1a;將不同編程語言&#xff08;C#, JS, VB等&#xff09;使用各自的編譯器&#xff0c;按照統…

JavaScript 原始值和引用值在變量復制時的異同

相比于其他語言&#xff0c;JavaScript 中的變量可謂獨樹一幟。正如 ECMA-262 所規定的&#xff0c;JavaScript 變量是松散類型的&#xff0c;而且變量不過就是特定時間點一個特定值的名稱而已。由于沒有規則定義變量必須包含什么數據類型&#xff0c;變量的值和數據類型在腳本…

mysql.service is not a native service, redirecting to systemd-sysv-install

字面意思&#xff1a;mysql.service不是本機服務&#xff0c;正在重定向到systemd sysv安裝 在CentOS上使用Systemd管理MySQL服務的具體步驟如下&#xff1a; 1、創建MySQL服務單元文件&#xff1a; 首先&#xff0c;你需要創建一個Systemd服務單元文件&#xff0c;以便Syste…

【Python筆記-設計模式】原型模式

一、說明 原型模式是一種創建型設計模式&#xff0c; 用于創建重復的對象&#xff0c;同時又能保證性能。 使一個原型實例指定了要創建的對象的種類&#xff0c;并且通過拷貝這個原型來創建新的對象。 (一) 解決問題 主要解決了對象的創建與復制過程中的性能問題。主要針對…

redhawk:使用ipf文件反標instance power

我正在「拾陸樓」和朋友們討論有趣的話題,你?起來吧? 拾陸樓知識星球入口 往期文章鏈接: Redhawk:Input Data Preparation 使用ptpx和redhawk報告功耗時差別總是很大,如果需要反標top/block的功耗值可以在gsr文件中使用BLOCK_POWER_FOR_SCALING的命令

Verilog刷題筆記35

題目&#xff1a; Create a 1-bit wide, 256-to-1 multiplexer. The 256 inputs are all packed into a single 256-bit input vector. sel0 should select in[0], sel1 selects bits in[1], sel2 selects bits in[2], etc. 解法&#xff1a; module top_module( input [255:…

Spring Cloud Alibaba-05-Gateway網關-02-斷言(Predicate)使用

Lison <dreamlison163.com>, v1.0.0, 2023.10.20 Spring Cloud Alibaba-05-Gateway網關-02-斷言(Predicate)使用 文章目錄 Spring Cloud Alibaba-05-Gateway網關-02-斷言(Predicate)使用通過時間匹配通過 Cookie 匹配通過 Header 匹配通過 Host 匹配通過請求方式匹配通…

C# CAD2016 cass10宗地Xdata數據寫入

一、 查看cass10寫入信息 C# Cad2016二次開發獲取XData信息&#xff08;二&#xff09; 一共有81條數據 XData value: QHDM XData value: 121321 XData value: SOUTH XData value: 300000 XData value: 141121JC10720 XData value: 權利人 XData value: 0702 XData value: YB…

2.居中方式總結

居中方式總結 經典真題 怎么讓一個 div 水平垂直居中 盒子居中 首先題目問到了如何進行居中&#xff0c;那么居中肯定分 2 個方向&#xff0c;一個是水平方向&#xff0c;一個是垂直方向。 水平方向居中 水平方向居中很簡單&#xff0c;有 2 種常見的方式&#xff1a; 設…

java面試題之mybatis篇

什么是ORM&#xff1f; ORM&#xff08;Object/Relational Mapping&#xff09;即對象關系映射&#xff0c;是一種數據持久化技術。它在對象模型和關系型數據庫直接建立起對應關系&#xff0c;并且提供一種機制&#xff0c;通過JavaBean對象去操作數據庫表的數據。 MyBatis通過…

MATLAB練習題:randperm函數的練習題

?講解視頻&#xff1a;可以在bilibili搜索《MATLAB教程新手入門篇——數學建模清風主講》。? MATLAB教程新手入門篇&#xff08;數學建模清風主講&#xff0c;適合零基礎同學觀看&#xff09;_嗶哩嗶哩_bilibili MATLAB中有一個非常有用的函數&#xff1a;randperm函數&…

華為算法題 go語言或者ptython

1 給定一個整數數組 nums 和一個整數目標值 target&#xff0c;請你在該數組中找出 和為目標值 target 的那 兩個 整數&#xff0c;并返回它們的數組下標。 你可以假設每種輸入只會對應一個答案。但是&#xff0c;數組中同一個元素在答案里不能重復出現。 你可以按任意順序返…

如何進行高性能架構的設計

一、前端優化 減少請求次數頁面靜態化邊緣計算 增加緩存控制&#xff1a;請求頭 減少圖像請求次數&#xff1a;多張圖片變成 一張。 減少腳本的請求次數&#xff1a;css和js壓縮&#xff0c;將多個文件壓縮成一個文件。 二、頁面靜態化 三、邊緣計算 后端優化 從三個方面進…