搞懂Java橋接模式,打破繼承侷限性,輕鬆實現多維變化

帶你聊技術發表於2023-11-29

來源:mikechen的網際網路架構

晦澀難懂的橋接模式,這篇文章一次就說清楚了。

瞭解並掌握橋接模式,對理解物件導向設計有非常大的幫助,值得深入學習。

 7 大設計原則(41張圖解、2萬多字)

5 大建立型設計模式總結,20 張圖徹底掌握

橋接 15 

搞懂Java橋接模式,打破繼承侷限性,輕鬆實現多維變化


01
  橋接

橋接模式(Bridge)是一種結構性模式,指將抽象與實現分離,使它們可以獨立變化。

概念有點晦澀難懂,我們用例子來幫助理解。

假設:一個水果類 fruit ,它可以擴充套件出兩個子類:香蕉 banana 、蘋果 apple。們需要擴充套件類層次結構使其包含顏色,因此建立了名為紅色 Red 和黃色 Yellow 的顏色子類。

由於已經有兩個子類, 現在需要建立四個類才能覆蓋所有組合,例如:黃色蘋果 YellowApple、紅色香蕉 RedBanana­。

搞懂Java橋接模式,打破繼承侷限性,輕鬆實現多維變化

在這樣的層次結構中,新增形狀和顏色將導致程式碼複雜程度指數增長。

我們每新增一種水果,就需要新增兩個子類(兩種顏色),每新增一種新的顏色,就需要新增三個子類, 即每種水果一個。

以此類推,所有組合類的數量將以幾何級數增長,情況會越來越糟糕。

問題的根本原因在於:我們是在兩個獨立的維度(水果與顏色)上進行擴充套件,這在處理繼承時是很常見的問題。

橋接模式將繼承改為組合的方式,非常完美的解決了這個問題。

我們抽取其中一個維度,讓它成為獨立的類層次, 這樣就可以在初始類中引用這個新層次的物件, 從而使得一個類不必擁有所有的狀態和行為。

搞懂Java橋接模式,打破繼承侷限性,輕鬆實現多維變化

將顏色相關的程式碼抽取到擁有紅色、黃色兩個子類的顏色類中, 然後在水果類中新增一個指向某一顏色物件的引用成員變數。

水果類就可以將所有與顏色相關的工作委派給連入的顏色物件,這樣的引用就成為了 水果顏色 之間的橋樑。

之後,我們再新增顏色,就不用修改水果的類層次了。

02
  橋接的結構

橋接模式的 UML 類圖:

搞懂Java橋接模式,打破繼承侷限性,輕鬆實現多維變化

橋接模式的主要構成:

  • 抽象化(Abstraction):定義抽象類,幷包含一個對實現化(Implementor)的引用,Abstraction 充當橋接類;

  • 擴充套件抽象化(Refined Abstraction):是抽象化(Abstraction)的子類,實現父類中的業務方法,並透過組合關係呼叫實現化(Implementor)中的業務方法;

  • 實現化(Implementor):定義實現化角色的介面,供擴充套件抽象化(Refined Abstraction)呼叫;

  • 具體實現化(Concrete Implementor):給出實現化(Implementor)介面的具體實現。


03
  橋接的實現

我們透過一個例項,來看看橋接模式是如何實現的。

這裡仍然以水果與顏色為例,用這兩個獨立的維度,來實現給不同的水果新增上不同的色彩。

1)ColorAPI :用於新增顏色的介面




public interface ColorAPI {    public void paint();}


2)YellowColorAPI :新增黃色的實現類







public class YellowColorAPI implements ColorAPI {    @Override    public void paint() {        System.out.println("新增黃色");    }}


3)RedColorAPI :新增紅色的實現類








public class RedColorAPI implements ColorAPI{    @Override    public void paint() {        System.out.println("新增紅色");    }}


4)Fruit :抽象水果類










public abstract class Fruit{    protected ColorAPI colorAPI;    //新增一個顏色的成員變數以呼叫 ColorAPI 的方法來實現給不同的水果新增顏色
   public void setDrawAPI(ColorAPI colorAPI) {      //注入顏色成員變數        this.colorAPI= colorAPI;    }    public abstract void draw();        }


5)Apple :蘋果類








public class Circle extends Fruit{    @Override    public void draw() {        System.out.print("我是蘋果");        colorAPI.paint();    }}


6)Banana :香蕉類








public class Rectangle extends Fruit{    @Override    public void draw() {        System.out.print("我是香蕉");        colorAPI.paint();    }}


7)Client:客戶端






















public class Client {
   public static void main(String[] args) {        //建立一個蘋果        Fruit fruit= new Apple();        //給蘋果紅色的顏料        fruit.setDrawAPI(new RedColorAPI());        //上色        fruit.draw();

       //建立一個香蕉        Fruit fruit1 = new Banana();        //給香蕉黃色的顏料        fruit1.setDrawAPI(new YellowColorAPI());        //上色        fruit1.draw();
   }}


8)結果



我是蘋果畫上紅色我是香蕉畫上黃色

9)新增一種水果

如果要新增一種水果桔子,不必將每一種顏色都增加一個,只需要新增一個水果類,在客戶端呼叫時,按照需求來挑選即可。

例如,新增桔子:








public class Triangle extends Fruit{    @Override    public void draw() {        System.out.println("我是桔子");        colorAPI.paint();    }}


10)增一種顏色

如果要新增一種顏色,不用去更改類的層次,只需要增加一個新的顏色,實現 ColorAPI 的介面就行了。

例如,新增一個顏色黑色:







public class BlackColorAPI implements ColorAPI {    @Override    public void paint() {        System.out.println("畫上黑色");    }}


實現系統可能有多個角度分類(例如例子中的形狀與顏色),每一種分類都有可能變化。

橋接模式用組合關係代替繼承關係來實現,將這種多角度分離出來讓他們獨立變化,降低了抽象和實現這兩個可變維度的耦合度。

04
  橋接的使用場景

橋接模式種常見的使用場景:

  • 系統中某個類存在多個實現,但是這些實現不應該對客戶端產生影響;

  • 需要在系統中進行抽象化和實現化之間的解耦;

  • 需要在開發過程中靈活地切換和組合不同的抽象類和實現類。


05
  橋接的優缺點

橋接模式的優點:


  • 象與實現分離,擴充套件能力強;

  • 符合開閉原則、合成複用原則;

  • 實現細節對客戶透明。

橋接模式的缺點:

  • 由於聚合關係建立在抽象層,要求開發者針對抽象化進行設計與程式設計,能正確地識別出系統中兩個獨立變化的維度,這增加了系統的理解及設計難度。


總結
 

透過本文,我們瞭解並掌握橋接模式橋接模式將抽象與行為實現分離開來,保持了各部分的獨立性以及應對他們的功能擴充套件。

在實際專案中運用橋接模式時,值得注意以下 3 點:

  • 在設計類時,儘量遵循橋接模式的原則,尤其是對於那些可能變化的部分,需要將它們抽象出來;

  • 使用橋接模式時,需要確保抽象類和實現類之間的介面定義足夠清晰,以便於後續的擴充套件和維護;

  • 在具體實現中,我們需要採用工廠模式以及依賴注入等方式來建立和注入抽象和具體實現類。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2997892/,如需轉載,請註明出處,否則將追究法律責任。

相關文章