講到繼承的時候,總是喜歡用一個例子來講解,那就是畫圖,這裏有一個畫筆,可以畫正方形、長方形、圓形(這個大家都知道怎麼做吧,我就不解釋了)。但是現在我們需要給這些形狀進行上色,這裏有三種顏色:白色、灰色、黑色。這裏我們可以畫出3*3=9中圖形:白色正方形、白色長方形、白色圓形。。。。。。到這裏了我們幾乎到知道了這裏存在兩種解決方案:
方案一:爲每種形狀都提供各種顏色的版本。
方案二:根據實際需要對顏色和形狀進行組合。
我們我們採用方案一來實現的話,我們是不是也可以這樣來理解呢?爲每種顏色都提供各種形狀的版本呢?這個是完全的可以的。如下:
對於中兩個圖形,我們都會很清楚這樣一個問題:加入我們添加橢圓,我們是不是又要增加三種顏色呢?假如我們在增加一個綠色,我們就要增加其四種形狀了,繼續加。繼續加……每次增加都會增加若干個類(如果增加顏色則會增加形狀個數個類,若增加形狀則會增加顏色個數個類),這樣的情況我想每個程序員都不會想要吧!那麼我們看方案二。
方案二所提供的就是解決方法是:提供兩個父類一個是顏色、一個形狀,顏色父類和形狀父類兩個類都包含了相應的子類,然後根據需要對顏色和形狀進行組合。
對於有幾個變化的維度,我們一般採用方案二來實現,這樣除了減少系統中的類個數,也利於系統擴展。對於方案二的應用我們稱之爲橋接模式。
一、 模式定義
橋接模式即將抽象部分與它的實現部分分離開來,使他們都可以獨立變化。
橋接模式將繼承關係轉化成關聯關係,它降低了類與類之間的耦合度,減少了系統中類的數量,也減少了代碼量。
將抽象部分與他的實現部分分離這句話不是很好理解,其實這並不是將抽象類與他的派生類分離,而是抽象類和它的派生類用來實現自己的對象。這樣還是不能理解的話。我們就先來認清什麼是抽象化,什麼是實現化,什麼是脫耦。
抽象化:其概念是將複雜物體的一個或幾個特性抽出去而只注意其他特性的行動或過程。在面向對象就是將對象共同的性質抽取出去而形成類的過程。
實現化:針對抽象化給出的具體實現。它和抽象化是一個互逆的過程,實現化是對抽象化事物的進一步具體化。
脫耦:脫耦就是將抽象化和實現化之間的耦合解脫開,或者說是將它們之間的強關聯改換成弱關聯,將兩個角色之間的繼承關係改爲關聯關係。
對於那句話:將抽象部分與他的實現部分分離套用《大話設計模式》裏面的就是實現系統可能有多個角度分類,每一種角度都可能變化,那麼把這種多角度分類給分離出來讓他們獨立變化,減少他們之間耦合。
橋接模式中的所謂脫耦,就是指在一個軟件系統的抽象化和實現化之間使用關聯關係(組合或者聚合關係)而不是繼承關係,從而使兩者可以相對獨立地變化,這就是橋接模式的用意。
二、 模式結構
下圖是橋接模式的UML結構圖:
橋接模式主要包含如下幾個角色:
Abstraction:抽象類。
RefinedAbstraction:擴充抽象類。
Implementor:實現類接口。
ConcreteImplementor:具體實現類 。
三、 模式實現
模式場景我們就採用哪個畫圖的。其UML結構圖如下:
首先是形狀類:該類爲一個抽象類,主要提供畫形狀的方法:Shape.java
public abstract class Shape { Color color; public void setColor(Color color) { this.color = color; } public abstract void draw(); }
然後是三個形狀 。圓形:Circle.java
public class Circle extends Shape{ public void draw() { color.bepaint("正方形"); } }
長方形:Rectangle.java
public class Rectangle extends Shape{ public void draw() { color.bepaint("長方形"); } }
正方形:Square.java
public class Square extends Shape{ public void draw() { color.bepaint("正方形"); } }
顏色接口:Color.java
public interface Color { public void bepaint(String shape); }
白色:White.java
public class White implements Color{ public void bepaint(String shape) { System.out.println("白色的" + shape); } }
灰色:Gray.java
public class Gray implements Color{ public void bepaint(String shape) { System.out.println("灰色的" + shape); } }
黑色:Black.java
public class Black implements Color{ public void bepaint(String shape) { System.out.println("黑色的" + shape); } }
客戶端:Client.java
public class Client { public static void main(String[] args) { //白色 Color white = new White(); //正方形 Shape square = new Square(); //白色的正方形 square.setColor(white); square.draw(); //長方形 Shape rectange = new Rectangle(); rectange.setColor(white); rectange.draw(); } }
運行結果:
白色的正方形
白色的長方形
四、 模式優缺點
優點
1、分離抽象接口及其實現部分。提高了比繼承更好的解決方案。
2、橋接模式提高了系統的可擴充性,在兩個變化維度中任意擴展一個維度,都不需要修改原有系統。
3、實現細節對客戶透明,可以對用戶隱藏實現細節。
缺點
1、橋接模式的引入會增加系統的理解與設計難度,由於聚合關聯關係建立在抽象層,要求開發者針對抽象進行設計與編程。
2、橋接模式要求正確識別出系統中兩個獨立變化的維度,因此其使用範圍具有一定的侷限性。
五、 模式使用場景
1、如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承聯繫,通過橋接模式可以使它們在抽象層建立一個關聯關係。
2、對於那些不希望使用繼承或因爲多層次繼承導致系統類的個數急劇增加的系統,橋接模式尤爲適用。
3、一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展。
六、 模式總結
1、橋接模式實現了抽象化與實現化的脫耦。他們兩個互相獨立,不會影響到對方。
2、對於兩個獨立變化的維度,使用橋接模式再適合不過了。
3、對於“具體的抽象類”所做的改變,是不會影響到客戶。
原文地址:https://www.cnblogs.com/chenssy/p/3317866.html