我學設計模式 之 橋接模式

sz_bdqn發表於2010-09-22

我學設計模式之橋樑模式

 

1.  簡介

橋樑模式是是物件結構模式。橋樑模式又稱柄體模式或介面模式、橋接模式。橋樑模模式用意:將抽象化與實現化脫耦,使得二者可以獨立的變化。

 

熟悉這個模式對於理解物件導向的設計原則,包括“開閉原則(OCP)”以及“組合/聚合原則(CARP)”都很有幫助。

 

在繼續學這個模式之前先來複習了這幾個概念:

抽象化:存在於多個實體中的共同概念性的聯絡,就是抽象化。做為一個過程,抽象化就是忽略一些資訊,從而把不同的實體當做同樣的實體對待。

 

實現化:抽象化給出的具體實現,就是實現化。

 

脫耦:就是兩個實體的行為的某種強關聯。而將它們的強關聯去掉,就是耦合的解脫。在橋接模式這裡是將抽象化和實體化之間的耦合解脫開,或者說將它們之間的強關聯改換成弱關聯。

 

強關聯:就是在編譯時期已經確定的,無法在執行時期改變的關聯;

弱關聯:就是可以動態確定並且可以在執行時期動態的改變的關聯。

 

顯然在javaC#這些面嚮物件語言中,繼承關係是強關聯,而聚合關係是弱關聯。將兩個角色之間的繼承關係改為聚合關係,就是將它們之間的強關聯改換成弱關聯。

 

 

開閉原則:對擴充套件開放,對修改關閉。這個原則說的是在設計一個模組的時候,應當使用這個模組可以在不被修改的前提下被擴充套件。換言之,應當可以在不修改原始碼的情況下改變這個模組的行為。

 

合成聚合複用原則:儘量使用合成/聚合,儘量不要使繼承。聚合表示一種弱的“擁有關係”,體現的是A物件可以包含B物件,但B物件不是A物件的一部分;合成則是一種強的‘擁有’關係,體現了嚴格的部分和整體的關係,部分和整體的生命週期一樣。

優先使用物件的合成/聚合將有助於你保持每個類被封裝,並被集中在單個任務上。這樣類和類的繼承層次會保持較小的規模,並且不太可能增長為不可控制的龐然大物。

 

 

2.  橋接模式的結構

下面是橋樑模式的UML圖:

 

這個系統包含兩個等級結構:

ü         由抽象化角色和修正抽象化角色組成的抽象化等級結構。

ü         由實現化和兩個具體實現化角色所組成的實現化等級結構。

 

橋樑模式所涉及的角色有:

Ø         抽象化角色:抽象化給出的定義,並儲存一個對實現化物件的引用。

Ø         修正抽象化角色:擴充套件抽象化角色,改變和修正父類對抽象化的定義。

Ø         實現化角色:這個角色給出實現化角色的介面,但不給出具體的實現。必須提出的是,這個介面不一定和抽象化角色的介面定義相同,實際上,這兩個介面可以非常不一樣。實現化角色應當只給出底層操作,而抽象化角色應當給出基於底層操作的更高一層的操作。

Ø         具體實現化角色:這個角色給出的實現化角色介面的具體實現。

 

 

3.  橋接模式的用法

用橋接模式來描述手機品牌與手機軟體的關係,是用Java來實現:

實現化的原始碼:

package com.zsw.bridge;

 

/**

 * 手機軟體

 * @author zsw

 * 20109260:49:29

 */

public abstract class HandSetSoft {

 

    public abstract void run();

}

 

具體實現化通訊錄:

package com.zsw.bridge;

 

/**

 * 通訊錄

 * @author zsw

 * 20109261:08:36

 */

public class HandSetSoftAddressList extends HandSetSoft {

 

    @Override

    public void run() {

       System.out.println("------執行手機通訊錄!!!");

    }

}

 

 

具體實現化遊戲:

package com.zsw.bridge;

/**

 * 手機遊戲

 * @author zsw

 * 20109260:49:29

 */

public class HandSetSoftGame extends HandSetSoft{

 

    @Override

    public void run(){

       System.out.println("------執行手機遊戲!!!");

    }

}

 

 

 

抽象化手機品牌:

package com.zsw.bridge;

 

/**

 * 手機品牌

 * @author zsw

 * 20109260:49:29

 */

public abstract class HandSetBrand {

 

    protected HandSetSoft soft;

 

    public void setSoft(HandSetSoft soft) {

       this.soft = soft;

    }

   

    public abstract void run();

}

 

修正抽象化諾基亞手機:

package com.zsw.bridge;

 

public class HandSetBrandNOKIA extends HandSetBrand {

 

    @Override

    public void run() {

       System.out.print("諾基亞手機:");

       soft.run();

    }

}

 

 

修正抽象化三星手機:

package com.zsw.bridge;

 

public class HandSetBrandSamsung extends HandSetBrand {

 

    @Override

    public void run() {

       System.out.print("三星手機:");

       soft.run();

    }

}

客戶端:

package com.zsw.bridge;

 

public class Client {

    public static void main(String[] args) {

       HandSetBrand hsb = new HandSetBrandNOKIA();

       hsb.setSoft(new HandSetSoftGame());

       hsb.run();

      

       hsb.setSoft(new HandSetSoftAddressList());

        hsb.run();

      

       hsb = new HandSetBrandSamsung();

       hsb.setSoft(new HandSetSoftGame());

       hsb.run();

      

       hsb.setSoft(new HandSetSoftAddressList());

       hsb.run();

    }

}

顯示結果:

諾基亞手機:------執行手機遊戲!!!

諾基亞手機:------執行手機通訊錄!!!

三星手機:------執行手機遊戲!!!

三星手機:------執行手機通訊錄!!!

 

4.  橋接模式的應用場景

a)         驅動器軟體都可以是橋樑模式的應用。例如:印表機驅動器使用印表機的應用系統與印表機的驅動細節分割開,使得應用系統和印表機驅動器可以相對的獨立演化。JDBC驅動器,使用JDBC驅動器的應用程式就是抽象化角色,而驅動器本身扮演實現化角色。

b)        如何一個系統需要在夠敬愛呢的抽象化角色和具體角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的聯絡。

c)        設計要求實現化角色的任何改變不應當影響客戶端,或者說實現化角色的改變對客戶端是完全透明的。

d)        一個構件多於一個的抽象化角色和實現化角色,系統需要他們之間進行動態耦合。

e)         雖然在系統中使用整合式沒有問題的,但是由於抽象化角色和具體化角色需要獨立變化,設計要求需要獨立管理這兩者。

f)         實現橋樑模式是從底層到高層寫。熟悉.net中三層架構的朋友,應該知道,資料訪問、業務層、介面層,其實業務層依賴於資料訪問層,介面層依賴於業務邏輯層,這也相當於橋接模式。UML圖如下:

 

              看到這個例子應該更容易理解這個模式了吧。

 

 

g)        諾基亞、三星、索尼都是手機的製造商,手機當中都可以安裝一些軟體,如通訊錄、QQ、遊戲等等。現在要設計一個系統來描述這些手機品牌及手機軟體型別。設計的UML類圖可以如下:

 

 

5.  橋接模式的優缺點

優點:

將抽象化與實現化脫耦,使二者可以獨立的變化

        更好的體現軟體的設計原則:開閉原則(OCP)、組合/聚合複用原則(CARP

 

6.  參考文獻

a)         Java與模式》

b)        《大話設計模式》

 

待續……………..

 

     只要深入地理解了設計原則,很多設計模式其實就是原則的應用而已,或許在不知不覺中就在使用設計模式了。

相關文章