Bridge模式也叫橋接模式,是由GoF提出的23種軟件設計模式的一種。Bridge模式在調用方與被調用方之間使用一個起着“橋”作用的類,用來支持類的多方向擴展。
Bridge模式是構造型的設計模式之一。Bridge模式基於類的最小設計原則,通過使用封裝,聚合以及繼承等行爲來讓不同的類承擔不同的責任。它的主 要特點是把抽象(abstraction)與行爲實現(implementation)分離開來,從而可以保持各部分的獨立性以及應對它們的功能擴展。
面向對象的程序設計(OOP)裏有類繼承(子類繼承父類)的概念,如果一個類或接口有多個具體實現子類,如果這些子類具有以下特性:
- 存在相對並列的子類屬性。
- 存在概念上的交叉。
- 可變性。
我們就可以用Bridge模式來對其進行抽象與具體,對相關類進行重構。
爲
了容易理解,我們舉例說明一下,比如汽車類(Car),假設有2個子類,卡車類(Truck)與公交車類(Bus),它們有[設置引擎]這個動作行爲,通
過不同引擎規格的設置,可以將它們設置爲比如爲1500cc(Car1500),和2000cc(Car2000)的車。
這樣,不管是1500cc的卡車還是2000cc的卡車,抑或是1500cc的公交車還是2000cc的公交車,它們都可以是汽車類的子類,而且:
- 存在相對並列的子類屬性。汽車的種類,與汽車引擎規格是汽車的2個並列的屬性,沒有概念上的重複。
- 存在概念上的交叉。不管是卡車還是公交車,都有1500cc與2000cc引擎規格的車。
- 可變性。除了卡車,公交車之外,可能還有救火車;除了有1500cc與2000cc引擎規格的車之外,還可能有2500cc的車等等。
這樣一來,我們怎麼來設計汽車類呢?
1,方法一:通過繼承設計所有可能存在的子類。可能我們會想到下面的這種繼承關係:
汽車總類:Car
汽車子類 - 按種類分類:Bus,Truck
汽車子類 - 按引擎分類:Bus1500,Bus2000,Truck1500,Truck2000
這樣設置引擎這個動作就由各個子類加以實現。
但如果以後需要增加一種救火車(FireCar),以及增加一個引擎規格2500cc,需要實現的子類將會有:
Bus1500,Bus2000,Bus2500,Truck1500,Truck2000,Truck2500,FireCar1500,FireCar2000,FireCar2500
多達9個。
也就是說,這種設計方法,子類數目將隨幾何級數增長。
而且,Bus1500,Truck1500的引擎規格相同,它們的引擎設置動作應該是一樣的,但現在把它們分成不同的子類,難以避免執行重複的動作行爲。
2,方法二:分別爲Bus以及Truck實現設置不同引擎的方法
汽車總類:Car
汽車子類:Bus,Truck
然後在Bus類裏分別提供1500cc以及2000cc引擎的設置方法:
Bus extends Car {
public setEngine1500cc();
public setEngine2000cc();
}
在Truck類裏也分別提供1500cc以及2000cc引擎的設置方法:
Truck extends Car {
public setEngine1500cc();
public setEngine2000cc();
}
這種情況,子類的數量是被控制了。但一方面,如果每增加一種引擎規格,需要修改所有的汽車子類;另一方面,即使引擎的設置行爲一樣,但是不同的汽車子類卻需要提供完全一樣的方法。
在實際的應用開發中,以上2種方法都會造成遷一發而動全身,而且會存在大量的重複代碼。
Bridge模式可以很好的解決這類問題。
我們先看看Bridge模式的類圖描述:
[圖:出自wikipedia.org]
Client
Bridge模式的使用者
Abstraction
抽象類接口(接口或抽象類)
維護對行爲實現(Implementor)的引用
Refined Abstraction
Abstraction子類
Implementor
行爲實現類接口 (Abstraction接口定義了基於Implementor接口的更高層次的操作)
ConcreteImplementor
Implementor子類
我們來看看怎麼應用Bridge模式來設計汽車類。
抽象 - Abstraction類:汽車類及其子類:
Car:汽車總類
Truck:汽車子類 - 卡車類。
Bus:汽車子類 - 公交車類。
行爲實現 - Implementor:汽車引擎設置的行爲類及子類
SetCarEngine:汽車引擎的設置接口
SetCarEngine1500cc:設置1500cc引擎
SetCarEngine2000cc:設置2000cc引擎
Client類:使用Bridge模式
Client:測試
代碼:
- //測試
- public class Client {
- public static void main(String[] args) {
- SetCarEngine carEngine1500cc = new SetCarEngine1500cc();
- SetCarEngine carEngine2000cc = new SetCarEngine2000cc();
- Car truck1500cc = new Truck(carEngine1500cc);
- Car truck2000cc = new Truck(carEngine2000cc);
- truck1500cc.setEngine();
- truck2000cc.setEngine();
- Car bus1500cc = new Bus(carEngine1500cc);
- Car bus2000cc = new Bus(carEngine2000cc);
- bus1500cc.setEngine();
- bus2000cc.setEngine();
- }
- }
- /** "Abstraction" */
- //汽車類的抽象
- abstract class Car {
- SetCarEngine setCarEngine;
- public abstract void setEngine();
- }
- /** Refined Abstraction */
- //Abstraction子類:這裏爲汽車抽象類的子類
- class Truck extends Car {
- public Truck(SetCarEngine setCarEngine) {
- this .setCarEngine = setCarEngine;
- }
- public void setEngine() {
- System.out.print("Set Truck Engine: " );
- setCarEngine.setEngine();
- }
- }
- class Bus extends Car {
- public Bus(SetCarEngine setCarEngine) {
- this .setCarEngine = setCarEngine;
- }
- public void setEngine() {
- System.out.print("Set Bus Engine: " );
- setCarEngine.setEngine();
- }
- }
- /** "Implementor" */
- //汽車類的行爲實現
- interface SetCarEngine {
- public void setEngine();
- }
- /** ConcreteImplementor */
- //行爲實現子類
- class SetCarEngine1500cc implements SetCarEngine {
- public void setEngine() {
- System.out.println("1500cc" );
- }
- }
- class SetCarEngine2000cc implements SetCarEngine {
- public void setEngine() {
- System.out.println("2000cc" );
- }
- }
//測試
public class Client {
public static void main(String[] args) {
SetCarEngine carEngine1500cc = new SetCarEngine1500cc();
SetCarEngine carEngine2000cc = new SetCarEngine2000cc();
Car truck1500cc = new Truck(carEngine1500cc);
Car truck2000cc = new Truck(carEngine2000cc);
truck1500cc.setEngine();
truck2000cc.setEngine();
Car bus1500cc = new Bus(carEngine1500cc);
Car bus2000cc = new Bus(carEngine2000cc);
bus1500cc.setEngine();
bus2000cc.setEngine();
}
}
/** "Abstraction" */
//汽車類的抽象
abstract class Car {
SetCarEngine setCarEngine;
public abstract void setEngine();
}
/** Refined Abstraction */
//Abstraction子類:這裏爲汽車抽象類的子類
class Truck extends Car {
public Truck(SetCarEngine setCarEngine) {
this.setCarEngine = setCarEngine;
}
public void setEngine() {
System.out.print("Set Truck Engine: ");
setCarEngine.setEngine();
}
}
class Bus extends Car {
public Bus(SetCarEngine setCarEngine) {
this.setCarEngine = setCarEngine;
}
public void setEngine() {
System.out.print("Set Bus Engine: ");
setCarEngine.setEngine();
}
}
/** "Implementor" */
//汽車類的行爲實現
interface SetCarEngine {
public void setEngine();
}
/** ConcreteImplementor */
//行爲實現子類
class SetCarEngine1500cc implements SetCarEngine {
public void setEngine() {
System.out.println("1500cc");
}
}
class SetCarEngine2000cc implements SetCarEngine {
public void setEngine() {
System.out.println("2000cc");
}
}
執行Client,輸出結果:
C:/Bridge>javac *.java
C:/Bridge>java Client
Set Truck Engine: 1500cc
Set Truck Engine: 2000cc
Set Bus Engine: 1500cc
Set Bus Engine: 2000cc
C:/Bridge>