淺析設計模式-橋接模式

編程語言 設計模式 Java MySQL java學習與交流 java學習與交流 2017-08-27

定義

橋接模式(Bridge Pattern):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。它是一種對象結構型模式,又稱為柄體(Handle and Body)模式或接口(Interface)模式。

就是用來解決多維度變化的問題

拿T恤舉例,T恤根據印花的分類,有局部印花,全身印花,刺繡,然後又有不同的尺碼,每種類型都有 S,M,L。所以T恤有了兩個維度的變化,一個維度印花,一個維度尺碼

如果我們用多重繼承的方式來實現T恤,我們會先繼承T恤,生成三種印花T,然後每種印花T又各自派生三種尺碼的T

淺析設計模式-橋接模式

關於制定尺寸是有一套統一的規則的,和 T 恤印花類型並沒有的關聯,多重繼承的實現,每個類都要走一遍不同 size 的實現,會出現代碼冗餘。而且實現所有款式和尺碼的衣服,一共需要1+3+3*3=13個類。而且一旦每增加一個尺碼,每種印花類型又要派生多個子類,類的數量增長很快

現在我們用橋接模式來改造它,把這兩個維度拆開,獨立兩套繼承體系,然後在使用的時候組合在一起。首先以 T 恤的印花為主,一個繼承體系,有三種子類。然後尺碼在T恤類中是抽象類型的,不涉及具體的實現

淺析設計模式-橋接模式

而具體的實現由程序運行時動態指定。於是我們有 1+3+1+3=8個類,就可以實現所有尺寸的 T 恤。

同時,把這兩個維度剝離開,形成兩套繼承體系單獨維護。把類之間的靜態繼承關係,轉化為動態組合關係。兩個維度單獨變化,兩個維度的關聯採用抽象的方式連接,動態去實現,降低了耦合,同時容易擴展

這樣,兩個單獨的繼承體系通過某個抽象結構連接在一起,就稱為橋接。是組合優於繼承的典型模式

簡單設計

抽象類

有具體的業務也可以又抽象的業務方法

維持對實現類接口的一個引用

抽象實現類

實現抽象類的抽象方法

實現類接口

定義基本操作,具體實現交給子類

具體實現類

實現基本操作

簡單的類圖如下

淺析設計模式-橋接模式

運行時,為 Abstraction 的具體實例,動態組合 Implemetor 的具體實例,兩者橋接在一起

這兩個維度單獨變化,對任何一個維度的擴展都不會干擾到另一個維度

應用實例

菜單

假設我們有這樣一個需求,在一個頁面有三個菜單,菜單 A,菜單 B 和 菜單 C。菜單 A 和 菜單 B 有不同的 UI。菜單 C 只比 菜單 B 多了一個菜單選項,其他都一樣

每個菜單都有多個菜單選項,菜單中會有相同的菜單選項。菜單 A 有點贊、舉報;菜單 B 有舉報、刪除;菜單 C 有點贊、舉報、刪除

菜單選項有這幾種,點贊、舉報、刪除

菜單 B 還會隨著服務端返回的數據有變化,比如根據數據增加一個點讚的選項。每個菜單選項都會執行相應的業務

後面產品需求的變化,各個菜單的菜單選項可能發生增減,而每種菜單項內部的實現也可能發生變化

如果採用多重繼承,沒增加或者減少一個菜單項,都當成一個新類型的菜單,這樣靜態繼承創建菜單的方式,會讓類數量變多。而任何一個菜單選項實現的改變,又會影響擁有該類型選項的菜單代碼。維護起來很艱難

現在我們考慮用橋接模式來改造它

總結以上需求,我們這裡有兩個維度的變化:菜單UI+菜單項。UI 只有兩種,A 風格和 B風格。菜單項有三種,點贊、舉報、刪除。那麼就以菜單 UI 這個維度為菜單抽象類的基礎,形成一個菜單繼承體系;菜單項單獨出去形成另一個維度。使用的時候,再去動態設置菜單選項

淺析設計模式-橋接模式

在使用菜單的地方,動態地菜添加菜單項的實現

淺析設計模式-橋接模式

產品需求變化了,B 菜單不再有舉報了,我們在配置那個菜單時只移出 ReportMenuItem 就可以了

如果又多了一種 D 類型的菜單,還是這幾種菜單項,只是 UI 風格不再和 A、B 相同,只需要繼承 AbsMenu 創建 D 風格菜單。然後菜單項同樣動態組合進來

多用組合,少用繼承,代碼可以變得靈活。以後需求變化了,也可以減少改動量

JDBC

JDBC 針對 Java 平臺,對底層數據庫做了一個統一的封裝,也是一套規範。各個數據庫廠商自己去實現

比如我們對一個數據庫查詢,可以使用下面的簡單模板

淺析設計模式-橋接模式

淺析設計模式-橋接模式

這個 JDBC 的核心類有

  • DriverManager

  • Connection

  • Driver

...

觀察上面的數據庫連接過程,發現我們面向的是 JDBC 的 API 進行編程,而具體的實現通過各個廠商生產的驅動程序

總整體上看,JDBC 也是橋接模式的一種。JDBC 的 API 和數據庫查詢過程、應用程序為抽象部分,而各個廠商實現的驅動為實現部分。這兩套獨立變化,可以在運行時為抽象選擇實現,將兩者橋接在一起

橋接通過 DriverManager 來實現,兩個維度,API 的應用和驅動程序的實現,各自形成一套繼承體系,在運行時橋接在一起

比如 A 應用,可以用 Oracle,也可以用 MySQL,只需要更換驅動了,應用內的代碼基本不用改動

淺析設計模式-橋接模式

擴展思考

這裡只處理了兩個維度,如果有多維度變化怎麼辦?

那就再加個實現,然後與當前抽象橋接在一起

還是拿 T 恤舉例,這時候,我們又多了一個新的維度顏色。而顏色的實現是可以獨立變化的,和尺碼、印花沒有關聯。一共有三種類型的顏色,紅黃藍。所以我們再建立一個繼承體系,可以有這樣的實現

淺析設計模式-橋接模式

學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入Java學習交流群346942462,我們一起學Java!

相關推薦

推薦中...