橋接模式和組合模式的區別

????????橋接模式(Bridge Pattern)和組合模式(Composite Pattern)都是結構型設計模式,旨在解決對象結構的復雜性問題,但它們的應用場景和目的有所不同。以下是它們的區別:

1. 定義與目的

橋接模式(Bridge Pattern):

  • 定義:將抽象部分與它的實現部分分離,使它們可以獨立地變化。
  • 目的:主要解決在多維度變化情況下,類的爆炸性增長問題。通過將兩個或多個維度的變化分離到不同的類層次中,從而使得系統更具靈活性。

組合模式(Composite Pattern):

  • 定義:將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。
  • 目的:主要解決對象的層次結構問題,使得客戶端可以一致地處理單個對象和組合對象。

2. 主要使用場景

橋接模式:

  • 當一個類有多個變化維度,并且這些維度需要獨立變化時使用橋接模式。例如,一個圖形類可能有形狀和顏色兩個變化維度,那么可以將形狀和顏色分離為兩個獨立的層次結構。
  • 當不希望在抽象和實現之間產生緊耦合時。

組合模式:

  • 當需要表示對象的部分-整體層次結構時使用組合模式。
  • 當希望客戶端可以統一地處理單個對象和組合對象時。

3. 結構區別

????????橋接模式:包含兩個獨立的層次結構,一個是抽象部分,一個是實現部分。抽象部分包含對實現部分的引用。

????????組合模式:包含一個對象樹的層次結構,葉子節點表示基本對象,組合節點表示容器對象。容器對象可以包含葉子節點或其他容器節點。

4. 示例代碼對比

橋接模式(Bridge Pattern)

????????目的:將抽象部分與它的實現部分分離,使它們可以獨立地變化。

類比

????????想象一下,你在設計一種繪圖應用程序,這個應用程序可以繪制不同種類的形狀(例如,圓形和方形),而每種形狀可以用不同的顏色來繪制(例如,紅色和藍色)。在這種情況下,形狀與顏色是兩個獨立的維度。

如果不用橋接模式,你可能會為每種情況創建一個類:

  • 紅色的圓形
  • 藍色的圓形
  • 紅色的方形
  • 藍色的方形

????????這樣類的數量會隨著形狀和顏色的增加而成倍增長(組合爆炸)。

橋接模式的解決方案:

????????將形狀和顏色分開處理。你創建一個形狀的抽象類,并且它包含一個顏色的接口。然后你可以獨立地擴展形狀和顏色。

// 顏色接口
class Color {
public:virtual std::string fill() const = 0;virtual ~Color() = default;
};class Red : public Color {
public:std::string fill() const override {return "紅色";}
};class Blue : public Color {
public:std::string fill() const override {return "藍色";}
};// 形狀抽象類
class Shape {
protected:std::shared_ptr<Color> color;
public:Shape(std::shared_ptr<Color> col) : color(col) {}virtual std::string draw() const = 0;virtual ~Shape() = default;
};class Circle : public Shape {
public:Circle(std::shared_ptr<Color> col) : Shape(col) {}std::string draw() const override {return "繪制一個" + color->fill() + "的圓形";}
};class Square : public Shape {
public:Square(std::shared_ptr<Color> col) : Shape(col) {}std::string draw() const override {return "繪制一個" + color->fill() + "的方形";}
};// 使用
int main() {std::shared_ptr<Color> red = std::make_shared<Red>();std::shared_ptr<Color> blue = std::make_shared<Blue>();std::shared_ptr<Shape> redCircle = std::make_shared<Circle>(red);std::shared_ptr<Shape> blueSquare = std::make_shared<Square>(blue);std::cout << redCircle->draw() << std::endl; // 輸出: 繪制一個紅色的圓形std::cout << blueSquare->draw() << std::endl; // 輸出: 繪制一個藍色的方形return 0;
}

組合模式(Composite Pattern)

????????目的:將對象組合成樹形結構以表示“部分-整體”的層次結構,使得用戶對單個對象和組合對象的使用具有一致性。

類比

????????想象一下,你在設計一個公司組織架構,這個組織架構中有部門和員工。部門可以包含子部門和員工,子部門又可以包含員工或更多的子部門,形成一個樹形結構。

組合模式的解決方案:

????????你創建一個通用的組件接口,它可以表示部門和員工,然后通過組合對象來表示部門,通過葉子對象來表示員工。

#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>// 組件接口
class Employee {
public:virtual void showDetails() const = 0;virtual void add(std::shared_ptr<Employee> employee) {}virtual void remove(std::shared_ptr<Employee> employee) {}virtual ~Employee() = default;
};// 葉子節點
class Developer : public Employee {
private:std::string name;
public:Developer(const std::string& devName) : name(devName) {}void showDetails() const override {std::cout << "開發者: " << name << std::endl;}
};// 葉子節點
class Designer : public Employee {
private:std::string name;
public:Designer(const std::string& desName) : name(desName) {}void showDetails() const override {std::cout << "設計師: " << name << std::endl;}
};// 容器節點
class Manager : public Employee {
private:std::string name;std::vector<std::shared_ptr<Employee>> subordinates;
public:Manager(const std::string& mgrName) : name(mgrName) {}void showDetails() const override {std::cout << "經理: " << name << std::endl;for (const auto& subordinate : subordinates) {subordinate->showDetails();}}void add(std::shared_ptr<Employee> employee) override {subordinates.push_back(employee);}void remove(std::shared_ptr<Employee> employee) override {subordinates.erase(std::remove(subordinates.begin(), subordinates.end(), employee), subordinates.end());}
};// 使用
int main() {std::shared_ptr<Employee> dev1 = std::make_shared<Developer>("Alice");std::shared_ptr<Employee> dev2 = std::make_shared<Developer>("Bob");std::shared_ptr<Employee> des1 = std::make_shared<Designer>("Charlie");std::shared_ptr<Manager> mgr1 = std::make_shared<Manager>("Dave");mgr1->add(dev1);mgr1->add(dev2);mgr1->add(des1);std::shared_ptr<Employee> des2 = std::make_shared<Designer>("Eve");std::shared_ptr<Manager> generalManager = std::make_shared<Manager>("Frank");generalManager->add(mgr1);generalManager->add(des2);generalManager->showDetails();// 輸出:// 經理: Frank// 經理: Dave// 開發者: Alice// 開發者: Bob// 設計師: Charlie// 設計師: Evereturn 0;
}

總結

  • 橋接模式:
    • 用于分離抽象和實現,使它們可以獨立變化。
    • 適用于多維度變化的場景,如形狀和顏色的組合。
  • 組合模式:
    • 用于構建對象的樹形結構,使得單個對象和組合對象可以一致地處理。
    • 適用于表示部分-整體層次結構的場景,如公司組織架構。

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

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

相關文章

Qt 小項目 學生管理信息系統

主要是對數據庫的增刪查改的操作 登錄/注冊界面&#xff1a; 主頁面&#xff1a; 添加信息&#xff1a; 刪除信息&#xff1a; 刪除第一行&#xff08;支持多行刪除&#xff09; 需求分析&#xff1a; 用QT實現一個學生管理信息系統&#xff0c;數據庫為MySQL 要求&#xf…

14.數據容器-set集合

特點 無序的&#xff0c;元素不重復&#xff0c;自帶去重功能。 可以容納不同類型的元素數據。 # 定義一個空set my_set {} your_set set() my_set {aa, bb, bb, aa} # {aa, bb} print(my_set) 因為set集合是無序的&#xff0c;所以集合不支持下標索引訪問。所以set集合…

“量子躍遷與數據織網:深入探索K最近鄰算法在高維空間中的優化路徑、神經網絡融合技術及未來機器學習生態系統的構建“

&#x1f3bc;個人主頁&#xff1a;【Y小夜】 &#x1f60e;作者簡介&#xff1a;一位雙非學校的大二學生&#xff0c;編程愛好者&#xff0c; 專注于基礎和實戰分享&#xff0c;歡迎私信咨詢&#xff01; &#x1f386;入門專欄&#xff1a;&#x1f387;【MySQL&#xff0…

硬件選型規則

光源選型: 先用型號中帶H的&#xff0c;沒有的選標準的. 光源和光源控制器的搭配需要確保接口一致。 根據型號表中的最佳工作距離和相機的尺寸。 光源控制器選型&#xff1a; 首先選擇海康風格系列光源控制器考慮與光源的接口匹配。功率應該滿足接近光源功率。檢查是否退市…

【QNX+Android虛擬化方案】135 - QNX側如何Dump 88Q5152 MIBS報文計數

【QNX+Android虛擬化方案】135 - QNX側如何Dump 88Q5152 MIBS報文計數 一、讀取 88Q5152 MIBS 計數二、讀取 88Q5152 WDT 相關寄存器基于原生純凈代碼,自學總結 純技術分享,不會也不敢涉項目、不泄密、不傳播代碼文檔!!! 本文禁止轉載分享 !!! 匯總鏈接:《【QNX+Andro…

C#核心(15)繼承中的構造函數

前言 我們之前學過構造函數是什么東西&#xff0c;今天的內容也和構造函數緊密相關&#xff0c;一個繼承了父親的子類里面構造函數的規則是什么樣的&#xff0c;今天內容很簡單&#xff0c;請聽我慢慢講來。 基本概念 特點&#xff1a;當申明一個子類時&#xff0c;先執行父…

TVbox源貢獻指南

歡迎各路大佬踴躍提PR&#xff0c;分享爬蟲代碼。 源碼倉庫地址 https://github.com/lushunming/AndroidCatVodSpider 快速開始 本工程是一個完整的AndroidStudio工程&#xff0c;請你用AS打開編輯。 工程調試完畢后要需要導出生成jar文件配合軟件使用&#xff0c;執行根目…

FastAPI快速入門

文章目錄 了解FastAPI程序結構第一步&#xff0c;導入FastAPI第二步&#xff0c;創建一個app實例第三步&#xff0c;編寫一個 路徑操作裝飾器第五步、運行開發服務器uvicorn main:app --reload即可訪問api鏈接。符案例 聲明路徑參數聲明路徑參數的類型get請求查詢參數請求體如何…

云計算.運維.面試題

1、計算機能直接識別的語言( C )。 A、匯編語言 B、自然語言 C、機器語言 D、高級語言 2、應用軟件是指( D )。 A、所有能夠使用的軟件 B、能被各應用單位共同使用的某種軟件 C、所有計算機上都應使用的基本軟件D、專門為某一應用目的而編制的軟件 3、計算機的顯示器是一…

如何優雅地實現單例模式?內部靜態類還是雙重檢查鎖定?

在最近的一個項目中&#xff0c;我需要為一個核心配置類實現單例模式。在設計過程中&#xff0c;我發現要同時滿足延遲加載和線程安全這兩個要求&#xff0c;常見的實現方式有兩種&#xff1a;內部靜態類和雙重檢查鎖定&#xff08;Double-Checked Locking, DCL&#xff09;。 …

【計算機網絡】 —— 數據鏈路層(壹)

文章目錄 前言 一、概述 1. 基本概念 2. 數據鏈路層的三個主要問題 二、封裝成幀 1. 概念 2. 幀頭、幀尾的作用 3. 透明傳輸 4. 提高效率 三、差錯檢測 1. 概念 2. 奇偶校驗 3. 循環冗余校驗CRC 1. 步驟 2. 生成多項式 3. 例題 4. 總結 四、可靠傳輸 1. 基本…

golang實現簡單的redis服務

golang 手搓redis服務器倉庫地址:實現思路: golang 手搓redis服務器 倉庫地址: 倉庫: https://github.com/dengjiayue/my-redis.git 實現思路: ● 協議: tcp通信 ● 數據包: 長度(4byte)方法(1byte)數據json ● 數據處理: 單線程map讀寫 ○ 依次處理待處理隊列的請求(chan)…

智慧銀行反欺詐大數據管控平臺方案(八)

智慧銀行反欺詐大數據管控平臺的核心理念&#xff0c;在于通過整合先進的大數據技術、算法模型和人工智能技術&#xff0c;構建一個全面、智能、動態的反欺詐管理框架&#xff0c;以實現對金融交易的全方位監控、欺詐行為的精準識別和高效處理。這一理念強調數據驅動決策&#…

3D 生成重建019-LERF用文本在Nerf中開啟上帝之眼

3D 生成重建019-LERF用文本在Nerf中開啟上帝之眼 文章目錄 0 論文工作1 論文方法2 實驗結果 0 論文工作 人類利用自然語言描述物理世界&#xff0c;根據各種特性&#xff08;視覺外觀、語義、抽象關聯&#xff09;尋找具體的3D位置。在這項工作中&#xff0c;作者提出了語言嵌…

如何選擇合適的期刊投稿?從課題組經驗到在線工具的使用全解析

~~~本文是作者個人的經驗分享&#xff0c;建立在導師讓自己選刊的情況下~~~ 投稿選刊是科研過程中至關重要的一步&#xff0c;選刊過程可能讓許多初投稿的研究者感到迷茫和困惑&#xff1a;期刊那么多&#xff0c;如何找到最合適的&#xff1f; 本文將從多個角度介紹如何選擇投…

024、Docker與SSH在分布式系統中的實踐指南

1. Docker SSH配置最佳實踐 Docker容器通常不需要SSH服務來運行&#xff0c;因為它們設計為輕量級、無狀態的&#xff0c;并且通常通過Docker命令行界面與宿主機進行交互。但是&#xff0c;在某些情況下&#xff0c;您可能需要通過SSH訪問Docker容器進行調試、維護或其他操作。…

【kafka】消息隊列的認識,Kafka與RabbitMQ的簡單對比

什么是消息隊列&#xff1f; 消息隊列&#xff08;Message Queue&#xff0c;簡稱 MQ&#xff09;是一個在不同應用程序、系統或服務之間傳遞數據的機制。 它允許系統間異步地交換信息&#xff0c;而無需直接交互&#xff0c;確保消息的可靠傳輸。 想象一下&#xff0c;你正在…

.NET MAUI與.NET for Android/IOS的關系

2024年11月13日微軟發布了.Net9.0,我打算體驗一下。安裝好.Net9.0 SDK后發現Visual Studio識別不到9.0&#xff0c;但是通過命令行dotnet --info查看是正常的&#xff0c;后面看到了VS有版本可以升級&#xff0c;把VS升級到17.12.0就可以了。更新完打開以后看到如下界面 這里…

SqlDataAdapter

SqlDataAdapter 是 .NET Framework 和 .NET Core 中提供的一個數據適配器類&#xff0c;屬于 System.Data.SqlClient 命名空間&#xff08;或在 .NET 6 中屬于 Microsoft.Data.SqlClient 命名空間&#xff09;。它的作用是充當數據源&#xff08;如 SQL Server 數據庫&#xff…

【vivado】時序報告--best時序和worst時序

利用vivado進行開發時&#xff0c;生成best時序報告和worst時序報告。 best時序報告 slow選擇min_max&#xff0c;fast選擇none。 worst時序報告 fast選擇min_max&#xff0c;slow選擇none。