一、橋接模式的定義
橋接(Bridge)模式的定義如下:將抽象與實現分離,使它們可以獨立變化。它是用組合關系代替繼承關系來實現,從而降低了抽象和實現這兩個可變維度的耦合度。
- 第一種設計方案是為每一種形狀都提供一套各種顏色的版本。
- 第二種設計方案是根據實際需要對形狀和顏色進行組合。
采用方案二來進行設計系統中類的個數更少,且系統擴展更為方便。設計方案二即是橋接模式的應用。橋接模式將繼承關系轉換為關聯關系,從而降低了類與類之間的耦合,減少了代碼編寫量。
二、橋接模式優缺點
橋接(Bridge)模式的優點是:
- 由於抽象與實現分離,所以擴展能力強;
- 其實現細節對客戶透明。
缺點是:
由於聚合關系建立在抽象層,要求開發者針對抽象化進行設計與編程,這增加了系統的理解與設計難度。
三、橋接模式的實現
可以將抽象化部分與實現化部分分開,取消二者的繼承關系,改用組合關系。
橋接(Bridge)模式包含以下主要角色。
- 抽象化(Abstraction)角色:定義抽象類,並包含一個對實現化對象的引用。
- 擴展抽象化(Refined Abstraction)角色:是抽象化角色的子類,實現父類中的業務方法,並通過組合關系調用實現化角色中的業務方法。
- 實現化(Implementor)角色:定義實現化角色的接口,供擴展抽象化角色調用。
- 具體實現化(Concrete Implementor)角色:給出實現化角色接口的具體實現。
其結構圖如圖所示:
其實現如下:
public class BridgeTest { public static void main(String[] args) { Implementor imple=new ConcreteImplementorA(); Abstraction abs=new RefinedAbstraction(imple); abs.Operation(); } }
//實現化角色 interface Implementor { public void OperationImpl(); }
//具體實現化角色 class ConcreteImplementorA implements Implementor { public void OperationImpl() { System.out.println("具體實現化(Concrete Implementor)角色被訪問" ); } }
//抽象化角色 abstract class Abstraction { protected Implementor imple; protected Abstraction(Implementor imple) { this.imple=imple; } public abstract void Operation(); }
//擴展抽象化角色 class RefinedAbstraction extends Abstraction { protected RefinedAbstraction(Implementor imple) { super(imple); } public void Operation() { System.out.println("擴展抽象化(Refined Abstraction)角色被訪問" ); imple.OperationImpl(); } }
四、橋接模式的應用實例
由於橋接模式上面描述比較抽象,此處再舉一個關於包的例子進行分析:女士皮包有很多種,可以按用途分、按皮質分、按品牌分、按顏色分、按大小分等,存在多個維度的變化,所以采用橋接模式來實現女士皮包的選購比較合適。
本實例按用途分可選錢包(Wallet)和挎包(HandBag),按顏色分可選黃色(Yellow)和紅色(Red)。可以按兩個維度定義為顏色類和包類。
顏色類(Color)是一個維度,定義為實現化角色,它有兩個具體實現化角色:黃色和紅色,通過 getColor() 方法可以選擇顏色;包類(Bag)是另一個維度,定義為抽象化角色,它有兩個擴展抽象化角色:挎包和錢包,它包含了顏色類對象,通過 getName() 方法可以選擇相關顏色的挎包和錢包。
public class BagManage { public static void main(String[] args) { Bag bag = new HandBag(); bag.setColor(new Yellow()); System.out.println(bag.getName()); } } //實現化角色:顏色 interface Color { String getColor(); } //具體實現化角色:黃色 class Yellow implements Color { public String getColor() { return "yellow"; } } //具體實現化角色:紅色 class Red implements Color { public String getColor() { return "red"; } } //抽象化角色:包 abstract class Bag { protected Color color; public void setColor(Color color) { this.color=color; } public abstract String getName(); } //擴展抽象化角色:挎包 class HandBag extends Bag { public String getName() { return color.getColor()+"HandBag"; } } //擴展抽象化角色:錢包 class Wallet extends Bag { public String getName() { return color.getColor()+"Wallet"; } }
輸出結果為:
yellowHandBag
五、橋接模式的應用場景
橋接模式通常適用於以下場景。
- 當一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展時。
- 當一個系統不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加時。
- 當一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性時。
六、橋接模式模式的擴展
在軟件開發中,有時橋接(Bridge)模式可與適配器模式聯合使用。當橋接(Bridge)模式的實現化角色的接口與現有類的接口不一致時,可以在二者中間定義一個適配器將二者連接起來,其具體結構圖如圖所示: