1 意圖
將抽象部分與它的實現部分分離,使它們都可以獨立的變化。
2 別名
Handle/Body
3 動機
當一個抽象可能有多個實現時,通常用繼承來協調它們。抽象定義對該抽象的接口,而具體的子類則用不同的方式加以實現。但是此方法有時不夠靈活。繼承機制將抽象部分與它的實現部分固定在一起,使得難以對抽象部分和實現部分獨立地進行修改、擴充和重用。
讓我們考慮在一個用戶界面箱中,一個可移植的Windo抽象實現。例如,這一抽象部分應該允許用戶開發一些X Window System和IBM的Presentation Manager(PM)系統中都可以使用的應用程序。運用繼承機制,我們可以定義Window抽象類和它的兩個子類Xwindow和PMWindow,由它們分別實現不同系統平臺的Window界面。但是繼承機制有兩個不足之處:
-
1 擴展Window抽象使之適用于不同種類的窗口或新的系統平臺很不方便。假設有Window的一個子類IconWindow,它專門將Window抽象于圖標處理。為了使IconWindow支持兩個系統平臺,我們必須實現兩個新類XIconWindow和PMIIconWindow,更為糟糕的是,我們不得不為每一種類型的窗口都定義兩個類,而為了支持第三個系統平臺我們還必須為每一種窗口定義一個新的Window子類,如下圖所示
image.png - 2 繼承機制使得客戶代碼與平臺相關。每當客戶創建一個窗口,必須要實例化一個具體的類,這個類有特定的實現部分。例如,創建XWindow對象將Window抽象與XWindow的實現部分綁定起來,這使得客戶程序依賴于XWindow的實現部分。這將使得很難將客戶代碼移植到其它平臺上去。
客戶在創建窗口應該不涉及到其具體實現部分,僅僅是窗口的實現部分依賴于應用運行的平臺。這樣客戶代碼在創建窗口就不應涉及到特定的平臺。
Bridge 模式解決以上的方法是,將Window抽象和它的實現部分分別放在獨立的類層次結構中。其中一個類層次結構針對窗口接口,另外一個獨立的類層次結構針對平臺相關的接口實現部分,這個類層次結構的根類為WindowImp。例如XWindowImp子類提供了一個基于XWindow系統的實現,如下圖所示:
對Window子類的所有操作都是用WindowImp的接口中的抽象操作實現的,這就將窗口的抽象和系統平臺相關的實現部分分離開來。因此,我們將Window與WindowImp之間的關系稱之為橋接,因為它在抽象類與它的實現之間起到了橋梁作用,使它們可以獨立地變化。
4. 適應性
以下情況使用Bright模式:
- 1 你不希望在抽象和它的實現部分之間有一個固定的綁定關系。例如這種情況可能是因為,在程序運行時刻實現部分應可以被選擇或者切換;
- 類的抽象以及它的實現都可以通過生成子類的方法加以擴充,這時Bridge模式使你可以對不同的抽象接口和實現部分進行組合,并分別對它們擴充;
- 3 對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的代碼不必重新編譯;
- 4 (C + +)你想對客戶完全隱藏抽象的實現部分。在 C + +中,類的表示在類接口中是可見的;
- 5 正如在意圖一節的第一個類圖中所示的那樣,有許多類要生成。這樣一種類層次結構說明你必須將一個對象分解成兩個部分;
- 6 你想在多個對象間共享實現(可能使用引用計數),但同時要求客戶并不知道這一點。
5 結構
6 參與者
- Abstraction(Window)
——定義抽象類的接口
——維護一個指向Implemtor類型對象的指針 - RefinedAbstraction(IconWindow)
——擴充由Abstraction定義的接口 - Implementor(WindowImp)
——定義實現類的接口,該接口不一定要與Abstraction的接口完全一致,事實上這兩個接口可以完全不同。一般來講,Implementor接口僅提供基本操作,而Abstraction則定義了基于這些基本操作的較高層次的操作; - ConcreteImplementor(XWindowImp,PMWindowImp)
——實現Implementor接口并定義它的具體實現
7 協作
- Abstraction將client的請求轉發給它的Implementor對象
8 效果
Bridge模式有以下的一些優點:
- 1 分離接口和實現部分
- 2 提供可擴充性
- 3 實現細節對客戶的透明
9 實現
要注意的問題:
- 1 在僅有一個實現的時候,沒有必要創建一個抽象的Implementor類
- 2 創建正確的Implementor對象
- 3 共享Implementor對象
- 4 采用多重繼承機制