設計模式(結構型)-橋接模式

目錄

摘要

定義

類圖

角色

具體實現

優缺點

優點

缺點

使用場景

使用案例

JDBC 和橋接模式

總結


摘要

????????在軟件開發領域,隨著系統規模和復雜性的不斷攀升,如何設計出具有良好擴展性、靈活性以及可維護性的軟件架構成為關鍵挑戰。橋接模式作為一種重要的結構型設計模式,為解決這些問題提供了有效的方案。它通過巧妙的設計,將抽象部分與實現部分進行分離,使二者能夠獨立發展變化,極大地提升了軟件系統應對變化的能力。

定義

????????將抽象部分與它的實現部分分離,使它們都可以獨立地變化。在許多傳統設計中,抽象與實現緊密耦合,一旦其中一方發生改變,往往會對另一方產生較大影響,這無疑增加了系統的維護成本和復雜性。橋接模式則打破了這種束縛,通過聚合關系代替繼承關系,實現了抽象化和實現化部分的解耦。?

????????例如,在一個圖形繪制系統中,假設我們有不同類型的圖形(如圓形、矩形等),同時需要在不同的平臺(如 Windows、Mac 等)上進行繪制。若采用傳統的繼承方式,每一種圖形類型都需要為每個平臺創建一個子類,這樣會導致類的數量呈指數級增長,代碼的維護和擴展變得極為困難。而橋接模式可以將圖形的抽象(如 Shape 類)與具體的繪制實現(如 WindowsDrawingAPI、MacDrawingAPI 等實現類)分離,通過聚合關系將它們關聯起來,使得圖形類型和繪制平臺能夠獨立發展,大大簡化了系統的設計。

類圖

角色

  • Abstraction(抽象類):處于整個結構的上層,用于定義抽象的接口。它一般是抽象類而非接口,其中定義了一個 Implementor(實現類接口)類型的對象并維護該對象,通過這種方式與 Implementor 建立關聯關系。抽象類中聲明的方法往往依賴于 Implementor 中定義的操作來實現具體功能。?

  • RefinedAbstraction(提煉抽象類):對 Abstraction 定義的接口進行擴充。通常情況下,它不再是抽象類而是具體類,實現了在 Abstraction 中聲明的抽象業務方法。在其實現過程中,會調用在 Implementor 中定義的業務方法,從而將抽象與實現進行結合。?

  • Implementor(實現類接口):該接口定義了實現類的基本操作規范。需要注意的是,它的接口設計不一定要與 Abstraction 的接口完全一致,事實上二者可能差異較大。Implementor 接口主要聚焦于提供一些基礎的、底層的操作,這些操作的具體實現由其子類負責。通過這種抽象接口的定義,為不同的具體實現提供了統一的規范。?

  • ConcreteImplementor(具體實現類):具體實現 Implementor 接口的類,針對不同的業務需求和場景,在各個 ConcreteImplementor 中提供基本操作的不同實現。在程序運行過程中,ConcreteImplementor 對象會替換其父類對象,為抽象類提供具體的業務操作方法,實現實際的功能。

具體實現

  • Abstraction(抽象類):作為抽象層的代表,它為整個系統提供了一個高層次的抽象接口。以圖形繪制系統為例,抽象類 Shape 可以定義一些通用的圖形操作方法,如繪制(draw)、縮放(resize)等,但并不涉及具體的繪制邏輯。它持有一個實現類接口 IDrawingAPI 類型的對象,通過該對象來調用具體的繪制實現。

public abstract class Shape {?protected IDrawingAPI drawingAPI;?public Shape(IDrawingAPI drawingAPI) {?this.drawingAPI = drawingAPI;?}?public abstract void draw();?public abstract void resize(double factor);?
}
  • RefinedAbstraction(提煉抽象類):以 Circle 類為例,它繼承自 Shape 抽象類,是提煉抽象類的具體體現。在 Circle 類中,實現了 Shape 類中定義的 draw 和 resize 方法,并借助 drawingAPI 對象調用具體的繪制實現。

public class Circle extends Shape {?private double x, y, radius;?public Circle(double x, double y, double radius, IDrawingAPI drawingAPI) {?super(drawingAPI);?this.x = x;?this.y = y;?this.radius = radius;?}?@Override?public void draw() {?drawingAPI.drawCircle(x, y, radius);?}?@Override?public void resize(double factor) {?radius *= factor;?}?
}
  • Implementor(實現類接口):定義了具體實現類需要遵循的接口規范。在圖形繪制系統中,IDrawingAPI 接口定義了繪制圓形、矩形等圖形的方法。

public interface IDrawingAPI {?void drawCircle(double x, double y, double radius);?void drawRectangle(double x1, double y1, double x2, double y2);?
}
  • ConcreteImplementor(具體實現類):如 WindowsAPI 和 MacAPI 類,分別實現了 IDrawingAPI 接口,提供了在 Windows 和 Mac 平臺上的具體繪制實現。

public class WindowsAPI implements IDrawingAPI {?@Override?public void drawCircle(double x, double y, double radius) {?System.out.println("在Windows平臺繪制圓形,圓心:(" + x + ", " + y + "),半徑:" + radius);?}?@Override?public void drawRectangle(double x1, double y1, double x2, double y2) {?System.out.println("在Windows平臺繪制矩形,左上角:(" + x1 + ", " + y1 + "),右下角:(" + x2 + ", " + y2 + ")");?}?
}?
public class MacAPI implements IDrawingAPI {?@Override?public void drawCircle(double x, double y, double radius) {?System.out.println("在Mac平臺繪制圓形,圓心:(" + x + ", " + y + "),半徑:" + radius);?}?@Override?public void drawRectangle(double x1, double y1, double x2, double y2) {?System.out.println("在Mac平臺繪制矩形,左上角:(" + x1 + ", " + y1 + "),右下角:(" + x2 + ", " + y2 + ")");?}?
}

優缺點

優點

  • 實現抽象和實現的分離:這是橋接模式的核心優勢。通過將抽象部分與實現部分解耦,使得它們能夠獨立地進行演化。例如,在圖形繪制系統中,圖形類型的擴展(如新增三角形、菱形等圖形)不會影響到繪制平臺的實現,反之,繪制平臺的更新(如支持新的操作系統)也不會對圖形類型造成影響,大大提高了系統的靈活性和可維護性。?

  • 提高系統的可擴充性:在橋接模式下,兩個變化維度(抽象和實現)中的任意一個進行拓展,都無需對原有系統進行大規模修改。以消息發送系統為例,若要新增一種消息類型(如推送消息),只需在抽象部分添加相應的類,并在實現部分關聯已有的消息發送方式(如郵件、短信等);若要新增一種消息發送方式(如即時通訊工具),也只需在實現部分添加具體實現類,然后在需要使用的抽象類中進行關聯即可,符合開閉原則。?

  • 避免多層繼承的弊端:多層繼承方案容易違背類的單一職責原則,導致代碼復用性差,并且類的數量會隨著繼承層次的增加而迅速膨脹,使得系統變得復雜難以維護。橋接模式采用聚合關系替代繼承關系,有效避免了這些問題,使得系統結構更加簡潔清晰。

缺點

  • 增加系統的理解與設計難度:由于橋接模式中的聚合關聯關系建立在抽象層,這要求開發者在設計和編程時,需要從更高的抽象層次去思考和規劃,對開發者的抽象思維能力和設計經驗有較高要求。初學者可能較難理解和掌握這種設計方式,增加了學習和上手的難度。?

  • 使用范圍具有一定的局限性:橋接模式的應用依賴于正確識別出系統中兩個獨立變化的維度。然而,在一些復雜系統中,準確判斷和分離這兩個維度并非易事。如果對系統的分析不準確,強行使用橋接模式,可能不僅無法發揮其優勢,反而會使系統變得更加復雜混亂,因此其使用場景受到一定限制。

使用場景

  • 一個類存在兩個獨立變化的維度,且這兩個維度都需要進行拓展:例如在電商系統中,商品有不同的類別(如電子產品、服裝、食品等),同時有不同的促銷策略(如打折、滿減、贈品等)。類別和促銷策略這兩個維度相互獨立且都可能不斷擴展,使用橋接模式可以將商品類別抽象與促銷策略實現進行分離,方便系統根據業務發展進行功能擴展。?

  • 如果一個系統需要在構建的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承關系:以跨平臺的游戲開發為例,游戲中的角色具有各種行為(如移動、攻擊、防御等抽象行為),而這些行為在不同的游戲平臺(如 PC、手機、主機等)上有不同的實現方式。通過橋接模式,可以將角色行為的抽象與平臺相關的實現解耦,使游戲在不同平臺上的移植和擴展更加容易,提高了系統的靈活性。?

  • 對于那些不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加的系統:如在圖形編輯軟件中,圖形元素有多種類型(矩形、圓形、多邊形等),并且需要支持不同的顯示模式(普通模式、高清模式、3D 模式等)。若采用繼承方式,會產生大量的子類(每種圖形類型對應每種顯示模式都需要一個子類)。使用橋接模式,將圖形類型抽象與顯示模式實現分離,可以有效避免類的數量爆炸,簡化系統設計。

使用案例

JDBC 和橋接模式

????????JDBC(Java Database Connectivity)是 Java 語言中用于連接和操作數據庫的標準 API,它很好地體現了橋接模式的應用。在 JDBC 中,抽象部分是 Java.sql 包中定義的一系列接口,如 Connection、Statement、ResultSet 等,這些接口定義了與數據庫交互的抽象操作,如建立連接、執行 SQL 語句、獲取查詢結果等。而實現部分則是各個數據庫廠商提供的數據庫驅動,如 MySQL 的驅動、Oracle 的驅動等。不同的數據庫驅動實現了 Java.sql 包中的接口,提供了針對各自數據庫的具體操作實現。?

????????通過這種方式,Java 程序在使用 JDBC 操作數據庫時,無需關心具體使用的是哪種數據庫以及其底層實現細節,只需要通過抽象接口進行操作。當需要更換數據庫時,只需要更換對應的數據庫驅動(實現部分),而 Java 程序中使用 JDBC 接口的代碼(抽象部分)無需修改,極大地提高了代碼的可移植性和可維護性,充分發揮了橋接模式將抽象與實現分離的優勢。?

總結

????????橋接模式作為一種強大的結構型設計模式,通過獨特的設計理念和結構,有效地解決了軟件系統中抽象與實現耦合的問題,為構建靈活、可擴展的軟件架構提供了有力的支持。雖然它存在一定的應用門檻和局限性,但在合適的場景下應用,能夠顯著提升軟件系統的質量和開發效率,是開發者在軟件設計過程中不可或缺的重要工具。

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

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

相關文章

Go 微服務框架 | 中間件

文章目錄 定義中間件前置中間件后置中間件路由級別中間件 定義中間件 中間件的作用是給應用添加一些額外的功能,但是不會影響原有應用的編碼方式,想用的時候直接添加,不想用的時候也可以輕松去除,實現所謂的可插拔。中間件的實現…

leetcode 198. House Robber

本題是動態規劃問題。 第一步,明確并理解dp數組以及下標的含義 dp[i]表示從第0號房間一直到第i號房間(包含第i號房間)可以偷到的最大金額,具體怎么偷這里不考慮,第i1號及之后的房間也不考慮。換句話說,dp[i]也就是只考慮[0,i]號…

掌趣科技前端面試題及參考答案

你使用 Vue 的頻率如何,用得比較多嗎? 在前端開發工作中,我對 Vue 的使用較為頻繁。Vue 作為一款輕量級、易于上手且功能強大的前端框架,在眾多項目里都發揮著重要作用。 在日常的項目里,Vue 的組件化開發特性為我帶來了極大的便利。組件化能夠將頁面拆分成多個小的、可復…

深入解析Python爬蟲技術:從基礎到實戰的功能工具開發指南

一、引言:Python 爬蟲技術的核心價值 在數據驅動的時代,網絡爬蟲作為獲取公開數據的重要工具,正發揮著越來越關鍵的作用。Python 憑借其簡潔的語法、豐富的生態工具以及強大的擴展性,成為爬蟲開發的首選語言。根據 Stack Overflow 2024 年開發者調查,68% 的專業爬蟲開發者…

CSS 筆記——Flexbox(彈性盒布局)

目錄 1. Flex 容器與 Flex 項目 2. 主軸與交叉軸 3. Flex 容器的屬性 display flex-direction justify-content align-items align-content flex-wrap 4. Flex 項目的屬性 flex-grow flex-shrink flex-basis flex align-self 5. Flexbox 的優點 6. Flexbox 的…

Java學習手冊:Java反射與注解

Java反射(Reflection)和注解(Annotation)是Java語言中兩個強大的特性,它們在框架開發和復雜應用中扮演著重要角色。反射允許程序在運行時檢查和操作類、對象、接口、字段和方法,而注解則提供了一種元數據形…

JavaWeb遇到的問題匯總

問題一:(鍵值對最后一項沒有逗號) 在JSON字符串轉自定義對象和自定義對象轉JSON字符串時: 如圖所示:若忘記刪除鍵值對的最后一項沒有逗號時,則下一句轉換不會生效,應該刪除最后一項的逗號。 解…

模板引擎語法-變量

模板引擎語法-變量 文章目錄 模板引擎語法-變量(一)在Django框架模板中使用變量的代碼實例(二)在Django框架模板中使用變量對象屬性的代碼實例(三)在Django框架模板中使用變量顯示列表 (一&…

AUTO-RAG: AUTONOMOUS RETRIEVAL-AUGMENTED GENERATION FOR LARGE LANGUAGE MODELS

Auto-RAG:用于大型語言模型的自主檢索增強生成 單位:中科院計算所 代碼: https://github.com/ictnlp/Auto-RAG 擬解決問題:通過手動構建規則或者few-shot prompting產生的額外推理開銷。 貢獻:提出一種以LLM決策為中…

Python 基礎語法匯總

Python 語法 │ ├── 基本結構 │ ├── 語句(Statements) │ │ ├── 表達式語句(如賦值、算術運算) │ │ ├── 控制流語句(if, for, while) │ │ ├── 定義語句(def…

一文詳解ffmpeg環境搭建:Ubuntu系統ffmpeg配置nvidia硬件加速

在Ubuntu系統下安裝FFmpeg有多種方式,其中最常用的是通過apt-get命令和源碼編譯安裝。本文將分別介紹這兩種方式,并提供安裝過程。 一、apt-get安裝 使用apt-get命令安裝FFmpeg是最簡單快捷的方式,只需要在終端中輸入以下命令即可: # 更新軟件包列表 sudo apt-get updat…

Android 14 、15動態申請讀寫權限實現 (Java)

在 Android 14、15 中&#xff0c;Google 進一步優化了存儲權限系統&#xff0c;特別是寫權限的管理。以下是完整的 Java 實現方案&#xff1a; 1. AndroidManifest.xml 聲明權限 <!-- Android 14 存儲權限 --> <uses-permission android:name"android.permiss…

小剛說C語言刷題——第23講 字符數組

前面&#xff0c;我們學習了一維數組和二維數組的概念。今天我們學習一種特殊的數組&#xff0c;字符數組。 1.字符數組的概念 字符數組就是指元素類型為字符的數組。字符數組是用來存放字符序列或者字符串的。 2.字符數組的定義及語法 char ch[5]; 3.字符數組的初始化及賦…

用AI生成系統架構圖

DeepSeek+Drawio+SVG繪制架構圖-找到一種真正可行實用的方法和思路 1、使用DeepSeek生成SVG文件,導入drawio工具的方法 ?? 問題根源分析 錯誤現象: ? 導入時報錯包含 data:image/SVG;base64 和 %20 等 URL 編碼字符 ? 代碼被錯誤轉換為 Base64 格式(適用于網頁嵌入,但…

免費干凈!付費軟件的平替款!

今天給大家分享一款超棒的電腦錄屏軟件&#xff0c;簡直不要太好用&#xff01;它的界面特別干凈&#xff0c;沒有一點兒廣告&#xff0c;看起來特別清爽。 電腦錄屏 無廣告的錄屏軟件 這個軟件超方便&#xff0c;根本不用安裝&#xff0c;打開就能直接用。 它功能也很強大&am…

【XCP實戰】AUTOSAR架構下XCP從0到1開發配置實踐

目錄 前言 正文 1.CAN功能開發 1.1 DBC的制作及導入 1.2 CanTrcv模塊配置 1.3 Can Controller模塊配置 1.4 CanIf模塊配置 2.XCP模塊集成配置配置 2.1.XCP模塊配置 2.2.XCP模塊的Task Mapping 2.3.XCP模塊的初始化 3.在鏈接文件中定義標定段 4.編寫標定相關的測試…

Vitis: 使用自定義IP時 Makefile錯誤 導致編譯報錯

參考文章: 【小梅哥FPGA】 Vitis開發中自定義IP的Makefile路徑問題解決方案 Vitis IDE自定義IP Makefile錯誤&#xff08;arm-xilinx-eabi-gcc.exe: error: *.c: Invalid argument&#xff09;解決方法 Vitis 使用自定義IP時: Makefile 文件里的語句是需要修改的&#xff0c;…

Python中NumPy的統計運算

在數據分析和科學計算領域&#xff0c;Python憑借其豐富的庫生態系統成為首選工具之一&#xff0c;而NumPy作為Python數值計算的核心庫&#xff0c;憑借其高效的數組操作和強大的統計運算功能&#xff0c;廣泛應用于機器學習、信號處理、統計分析等場景。本文將系統介紹NumPy在…

C語言程序環境和預處理詳解

本章重點&#xff1a; 程序的翻譯環境 程序的執行環境 詳解&#xff1a;C語言程序的編譯鏈接 預定義符號介紹 預處理指令 #define 宏和函數的對比 預處理操作符#和##的介紹 命令定義 預處理指令 #include 預處理指令 #undef 條件編譯 程序的翻譯環境和執行環…

智能工廠調度系統設計方案研究報告

一、系統架構設計 1.1 物理部署架構 設備層&#xff1a;部署大量搭載多傳感器陣列的 AGV 智能循跡車&#xff0c;這些傳感器包括激光雷達、視覺相機、超聲波傳感器等&#xff0c;用于感知周圍環境信息&#xff0c;實現自主導航與避障功能&#xff1b;在每個工序節點處設置 RF…