橋接模式(bridge pattern)
-
橋接模式時將抽象部分與它的實現部分分離,使他們可以獨立的變化。它是一種對象結構型模式,又稱為柄體(Handle and Body)模式或者接口(interface)模式(組合)
以前使用的多層繼承結構,耦合性太強,且違反了單一職責原則,如下圖
如果以這種結構去設計程序的架構的話,拓展性會有很大的問題。
比如如果想增加一個新的電腦品牌,需要寫三個類,如果想增加一個電子產品,依舊要寫三個類,非常繁瑣,
違反了單一職責原則:每個類只負責一個東西,每個類只有一個功能。
而從上圖看出,每一個類的最終實現類都負責了不止一個事務,如聯想臺式:聯想是品牌,而臺式是電腦的品種。每個類拆分的不夠徹底
分析:這個場景有兩個變化的維度:品牌,類型
這里面的每個節點就是上面結構圖中的最終實現類。
將結構看成這樣,那我們在新增品牌的時候,只需要在x軸增加就好了,在新增類型的時候,只需要在y軸增加就好了,只要想辦法通過一個鏈接點把它連起來,就可以形成一個新的產品。
而這,就是橋接模式,
我們需要將原來的事物高度抽象,只要超過兩個場景變換維度的事物,就將其抽象出來,這個類型寫一個抽象類,品牌寫一個抽象類,通過一座橋將其連接起來,就可以構建產品
使用橋接模式來重寫該事務
首先創建品牌接口,
?package com.lyc.bridge;// 品牌,抽象類或者接口public interface Brand {void info();}
再寫品牌實現類
?package com.lyc.bridge;//聯想品牌public class Lenovo implements Brand{@Overridepublic void info() {System.out.print("聯想品牌");}}
?package com.lyc.bridge;//蘋果品牌public class Apple implements Brand{@Overridepublic void info() {System.out.print("Apple");}}
開始寫電腦橋接類,在類中建立連接品牌的橋(即定義品牌屬性,再寫品牌構造器,在寫電腦實現類的時候,無需再連接品牌類)這樣大大減少了這兩個事物的耦合度。
?package com.lyc.bridge;//抽象的電腦類//橋接類 用于將電腦與品牌進行關聯public ?class Computer {//組合,品牌 橋接模式,橋用于鏈接,與適配器模式不同protected Brand brand; //子類在使用的時候可以隨意設置品牌public Computer(Brand brand){this.brand = brand;}public void info(){//自帶品牌brand.info();}}
再寫電腦實現類
?package com.lyc.bridge;?public class Laptop extends Computer{public Laptop(Brand brand) {super(brand);}?@Overridepublic void info() {super.info();System.out.print("筆記本");}}
?package com.lyc.bridge;?public class Desktop extends Computer{public Desktop(Brand brand) {super(brand);}public void info(){super.info();System.out.print("臺式機");}}
最后進行測試:
?package com.lyc.bridge;?public class Test {public static void main(String[] args) {//蘋果筆記本Computer computer = new Laptop(new Apple());computer.info();System.out.println("");//聯盟臺式機Desktop desktop = new Desktop(new Lenovo());desktop.info();}}
效果:
這樣就品牌與類型相互分離了
注意事項:
-
抽象部分與實現部分需要分離,不能有過多的耦合
-
橋接模式適用于多個維度的變化,如果維度較少,使用繼承更加簡單
-
橋接模式會增加系統復雜度,謹慎使用
類圖:
橋接模式
-
好處分析:
-
橋接模式偶爾類似于多繼承方案,但是多繼承方案違背了類的單一職責原則,復用性較差,類的個數也非常多,橋接模式是比多繼承方案更好的解決方法,極大地減少了子類的個數,從而降低管理和維護的成本
-
橋接模式提高了系統的可擴容性,在兩個變化維度任意擴展一個維度,都不需要修改原有模式,符合開閉原則,就像一座橋,可以把兩個變化的維度連接起來。
-
-
缺點分析:
-
橋接模式的引入會增加系統的理解與設計難度,由于聚合關聯關系建立在抽象層,要求開發者針對抽象進行設計與編程
-
橋接模式要求正確識別出系統中兩個獨立變化的維度,因此適用范圍具有一定的局限性
-
-
最佳實踐
-
如果一個系統需要在構建的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承聯系,可以通過橋接模式使他們在抽象層建立一個關聯關系,抽象化角色和實現化角色可以以繼承的方式獨立擴展而互不影響,在程序運行時可以將動態將一個抽象化子類的對象和一個實現化子類的對象進行組合,及系統需要對抽象化角色和現實化角色進行動態耦合
-
一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展
-
雖然在系統中使用擴展是沒有問題的,但是由于抽象化角色和具體化角色需要獨立變化,設計需求需要獨立管理這兩者,對于那些不希望使用繼承或者因為多層次繼承導致系統類的個數急速增加的系統,橋接模式非常適合
-
-
使用實例
-
Java語言通過Java虛擬機實現了平臺的無關性
-
AWT中的Peer架構:在同一個頁面中,在window中與在Liunx中的畫面不一致,代碼一致,效果不同
-
JDBC驅動程序也是橋接模式的應用之一,JDBC本身就是一個抽象角色,他可以連接MySQL,也可以鏈接Oracle,與具體實現的角色進行分離
-
拓展:橋接模式+適配器模式?
橋接模式可以用在系統創建之初,就是類似于兩個相關維度,如果在后面添加和前兩個基本無關的維度,可以使用適配器模式將其連接起來。
我們應該將前面學習過的設計模式,嘗試將其應用到自身代碼中,加強理解!
希望對大家有所幫助!