在開始學java的時候老師講到繼承的時候,老是喜歡用一個例子來說解,那就是畫圖,這裏有一個畫筆,能夠畫正方形、長方形、圓形(這個你們都知道怎麼作吧,我就不解釋了)。可是如今咱們須要給這些形狀進行上色,這裏有三種顏色:白色、灰色、黑色。這裏咱們能夠畫出3*3=9中圖形:白色正方形、白色長方形、白色圓形。。。。。。到這裏了咱們幾乎到知道了這裏存在兩種解決方案:java
方案一:爲每種形狀都提供各類顏色的版本。程序員
方案二:根據實際須要對顏色和形狀進行組合。編程
咱們咱們採用方案一來實現的話,咱們是否是也能夠這樣來理解呢?爲每種顏色都提供各類形狀的版本呢?這個是徹底的能夠的。以下:設計模式
對於中兩個圖形,咱們都會很清楚這樣一個問題:加入咱們添加橢圓,咱們是否是又要增長三種顏色呢?假如咱們在增長一個綠色,咱們就要增長其四種形狀了,繼續加。繼續加……每次增長都會增長若干個類(若是增長顏色則會增長形狀個數個類,若增長形狀則會增長顏色個數個類),這樣的狀況我想每一個程序員都不會想要吧!那麼咱們看方案二。this
方案二所提供的就是解決方法是:提供兩個父類一個是顏色、一個形狀,顏色父類和形狀父類兩個類都包含了相應的子類,而後根據須要對顏色和形狀進行組合。spa
對於有幾個變化的維度,咱們通常採用方案二來實現,這樣除了減小系統中的類個數,也利於系統擴展。對於方案二的應用咱們稱之爲橋接模式。設計
橋接模式即將抽象部分與它的實現部分分離開來,使他們均可以獨立變化。code
橋接模式將繼承關係轉化成關聯關係,它下降了類與類之間的耦合度,減小了系統中類的數量,也減小了代碼量。對象
將抽象部分與他的實現部分分離這句話不是很好理解,其實這並非將抽象類與他的派生類分離,而是抽象類和它的派生類用來實現本身的對象。這樣仍是不能理解的話。咱們就先來認清什麼是抽象化,什麼是實現化,什麼是脫耦。blog
抽象化:其概念是將複雜物體的一個或幾個特性抽出去而只注意其餘特性的行動或過程。在面向對象就是將對象共同的性質抽取出去而造成類的過程。
實現化:針對抽象化給出的具體實現。它和抽象化是一個互逆的過程,實現化是對抽象化事物的進一步具體化。
脫耦:脫耦就是將抽象化和實現化之間的耦合解脫開,或者說是將它們之間的強關聯改換成弱關聯,將兩個角色之間的繼承關係改成關聯關係。
對於那句話:將抽象部分與他的實現部分分離套用《大話設計模式》裏面的就是實現系統可能有多個角度分類,每一種角度均可能變化,那麼把這種多角度分類給分離出來讓他們獨立變化,減小他們之間耦合。
橋接模式中的所謂脫耦,就是指在一個軟件系統的抽象化和實現化之間使用關聯關係(組合或者聚合關係)而不是繼承關係,從而使二者能夠相對獨立地變化,這就是橋接模式的用意。
下圖是橋接模式的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(); } }
運行結果:
白色的正方形
白色的長方形
一、分離抽象接口及其實現部分。提升了比繼承更好的解決方案。
二、橋接模式提升了系統的可擴充性,在兩個變化維度中任意擴展一個維度,都不須要修改原有系統。
三、實現細節對客戶透明,能夠對用戶隱藏實現細節。
一、橋接模式的引入會增長系統的理解與設計難度,因爲聚合關聯關係創建在抽象層,要求開發者針對抽象進行設計與編程。
二、橋接模式要求正確識別出系統中兩個獨立變化的維度,所以其使用範圍具備必定的侷限性。
一、若是一個系統須要在構件的抽象化角色和具體化角色之間增長更多的靈活性,避免在兩個層次之間創建靜態的繼承聯繫,經過橋接模式可使它們在抽象層創建一個關聯關係。
二、對於那些不但願使用繼承或由於多層次繼承致使系統類的個數急劇增長的系統,橋接模式尤其適用。
三、一個類存在兩個獨立變化的維度,且這兩個維度都須要進行擴展。
一、橋接模式實現了抽象化與實現化的脫耦。他們兩個互相獨立,不會影響到對方。
二、對於兩個獨立變化的維度,使用橋接模式再適合不過了。
三、對於「具體的抽象類」所作的改變,是不會影響到客戶。