橋接模式: Bridge

簡介

橋接模式是結構型模式 (Structural Patterns) 的一種.數據庫

Making even a simple change to a monolithic codebase is pretty hard because you must understand the entire thing very well. Making changes to smaller, well-defined modules is much easier.設計模式

若是軟件系統中某個類存在多個獨立變化的維度, 經過該模式能夠將這多個維度分離出來, 使他們能夠獨立擴展, 讓系統更加符合"單一職責原則 (SRP)". 與多層繼承方案不一樣, 它將多個獨立變化的維度設計爲多個獨立的繼承等級結構, 而且在抽象層創建一個抽象關聯, 該關聯關係相似一條鏈接多個獨立繼承結構的橋, 故名橋接模式.bash

橋接模式用一種巧妙的方式處理多層繼承存在的問題, 用抽象關聯取代了多層繼承,將類之間的靜態繼承關係轉換爲動態的對象組合關係, 使得系統更加靈活, 並易於擴展, 同時有效控制了系統中類的個數.架構

簡單的例子

interface Shape {
    val shapeType: ShapeType
}

abstract class Circle : Shape {
    val shapeType = TypeCircle
    abstract val shapeColor: ShapeColor
    ...
}

abstract class Square : Shape {
    val shapeType = TypeSquare
    abstract val shapeColor: ShapeColor
    ...
}

class RedCircle : Circle() {...}
class RedSquare : Square() {...}
class BlueCircle : Circle() {...}
class BlueSquare : Square() {...}
...
複製代碼

在這個例子中, 不管增長形狀, 仍是增長顏色, 都會致使子類數量快速增長. 解決方案是劃分紅兩個獨立變化的維度: Type 和 Color.ui

abstract Shape(val shapeColor: ShapeColor) {
    abstract val shapeType: ShapeType
}

class Circle(val shapeColor: ShapeColor) : Shape(ShapeColor) {
    val shapeType = TypeCircle
    ...
}

class Square(val shapeColor: ShapeColor) : Shape(ShapeColor) {
    val shapeType = TypeSquare
    ...
}
複製代碼

如今, 增長顏色不會再致使子類數量增長了. Shape 和 Color 直接的關係就是那座橋.spa

基本概念

在 GoF 中, 橋接模式的定義以下:.net

  1. Abstraction:擁有一個 Implementation 類型的對象引用
  2. Implementation:Implementation 和 Abstraction 接口並不必定徹底一致,實際上這兩個接口能夠徹底不同, Implementation 提供具體操做方法,而 Abstraction 提供更高層次的調用
  3. Concrete Implementation:實現 Implementation 接口,給出具體實現
  4. Refined Abstraction:擴展 Abstraction 中的接口定義
  5. Client: 鏈接 Abstraction 和 Implementation

真實的例子

僞代碼見: refactoring.guru/design-patt…設計

遙控器的基類 (Remote) 中包含一個設備的引用 (device), 全部的遙控器均可以經過通用的設備接口 (Device interface) 控制設備.代理

  • 通用設備接口使得遙控器代碼能夠複用於遙控多種不一樣的設備 (Radio / TV).
  • 經過繼承遙控器基類, 能夠實現只有兩個按鈕的簡單遙控器, 或是帶觸摸屏的複雜遙控器.

其它真實的例子

- 驅動程序 / JDBC

應用程序使用驅動程序的方式是橋接模式的一個常見例子.版本控制

外設驅動按照制定好的接口操做外設, 使用該驅動的應用是一個 Abstraction, 它的運行結果取決於它使用的是哪個外設+驅動. 每一個驅動程序都是適配器模式 (Adapter) 的一個例子, 而使用驅動程序的應用是橋接模式的一個例子. 橋接模式將應用的開發和驅動的開發分離開來.

JDBC 是用於執行 SQL 的 Java 接口, JDBC 驅動就是實現了該接口的類. 任何一個數據庫只要提供了 JDBC 驅動, Java 的數據庫應用程序就能夠操做它. JDBC 的這種架構將 Abstraction 和 Implementation 相分離, 使得數據庫應用和數據庫可以獨立的發展, 是 Bridge 模式的一個極好的例子.

- VCS (Version Control System)

IDEA 的 VSC, 或者 Sourcetree 之類的軟件, 均可以在一樣一套 UI 下, 用一樣的概念 (好比 History, Diff) 操做不一樣的版本控制系統 (好比 Git, Svn).

應用場景

當一個應用/類的某個功能要支持多個變體(好比支持多個數據源)

一個應用/類越大, 弄清楚或改動的的代價就越大. 對於一個變體的改動可能會致使整個應用/類內的大量改動, 這常常會致使各類問題. Bridge 模式能夠把應用/類拆分紅多個獨立的結構, 以後的改動就在各自的結構中, 讓代碼的改動影響最小化.

當一個類在多個正交的維度上可擴展時

Bridge 模式建議將每一個維度抽象成獨立的繼承關係, 這樣以前的類能夠將相關的功能和擴展代理給對應的維度去作, 而不是徹底本身作.

若是你但願支持運行時切換實現 (Implementation)

雖然不是最重要的, 但 Bridge 模式容許你切換 Abstraction 中引用的 Implementation.

這多是 Bridge 模式容易和策略模式 (Strategy) 混淆的一個緣由. 注意: 設計模式呈現的不只是最終的代碼, 還有解決問題的思路.

優缺點

優勢

  • 能夠用來建立跨平臺的應用.
  • Client 和 Abstraction 交互, 不暴露 Implementation 的細節.
  • 開閉原則: 能夠分別增長 Abstraction 和 Implementation 的子類而不相互影響.
  • 單一職責原則: Abstraction 或 Implementation 的開發人員能夠 Focus 各自的代碼.

缺點

  • 若是一個類的功能之間功能之間相關性較強, 使用 Bridge 模式可能會讓代碼變得更復雜.

和其它設計模式的關係

  • Bridge, State, Strategy (Adapter 在某種程度上也算) 有一些類似, 這些設計模式都採用了將功能代理給其它類去作的方式. 可是, 他們解決的問題並不相同. 設計模式呈現的不只是最終的代碼, 還有解決問題的思路.
  • Abstract Factory 能夠和 Bridge 一塊兒使用, 一般用於 Abstraction 只能使用特定的 Implementation 的狀況. 在這種狀況下, 能夠用 Abstract Factory 封裝 Client 代碼中創建 Abstraction 和 Implementation 鏈接的部分.
  • Builder 能夠和 Bridge 一塊兒使用, Director 做爲 Abstraction, 多個 Builder 做爲 Implementation.

@Uraka.Lee

相關文章
相關標籤/搜索