橋樑模式/Bridge
意圖/適用場景:
橋樑模式的意圖在於把“抽象”與“實現”解耦合,把強關聯轉變爲弱關聯。
所謂強關聯,就是在編譯時期已經確定的,無法在運行時期改變的關聯;所謂弱關聯,就是可以動態地確定並且可以在運行時期動態地改變的關聯。顯然,在Java語言中,繼承關係是強關聯,而聚合關係是弱關聯。
將兩個角色之間的繼承關係改爲聚合關係,就是將它們之間的強關聯改爲弱關聯。因此,橋樑模式中的所謂解耦合,就是指在一個軟件系統的抽象化和實現化之間使用聚合關係而不是繼承關係,從而使兩者都可以相對獨立地變化。
UML:
參與者:
- 抽象化角色(Abstraction):抽象化給出的定義,並保存一個對實現化對象的引用。
- 修正抽象化角色(RefinedAbstraction):擴展抽象化角色,改變和修正父類對抽象化的定義。
- 實現化角色(Implementor):實現類的接口,定義實現類的方法。這些方法與抽象化角色所提供的方法不需要相同,甚至可以完全不同。
- 具體實現化角色(ConcreteImplementor):實現化角色的具體實現類。
要點:
橋樑模式的系統中有兩個等級結構:
- 由抽象化角色和修正抽象化角色組成的抽象化等級結構。
- 由實現化角色和具體實現化角色所組成的實現化等級結構。
抽象化等級結構是提供給用戶或者系統其它部分使用的,是穩定不易變的;而實現化等級結構是可以替換的,比如在不同的環境中,使用不同的實現化,這也正是解耦合的目標。
應用實例:
AWT的Peer架構
Java語言具有跨平臺的功能。相同的代碼使用AWT庫繪製的界面,在不同的操作系統上功能相同,但外觀風格不同。這裏就應用了橋樑模式,把Java的AWT調用與操作系統native調用有效地解耦合。 在AWT庫中的每一個Component的子類都有一個ComponentPeer的子類與之匹配。所有的Component的子類都屬於一個等級結構,即抽象化等級結構;而所有的ComponentPeer的子類都屬於另一個等級結構,即實現化等級結構。Component類型和ComponentPeer類型通過Toolkit對象相互通信。
示例代碼:
[java]
// Source code from file:Abstraction.java
packagedesignPatterns.Bridge;
publicclass Abstraction {
protectedImplementor imp;
publicvoid operation() {
imp.operationImp();
}
}
// Source code from file:ConcreteImplementorA.java
packagedesignPatterns.Bridge;
publicclass ConcreteImplementorA implements Implementor {
publicvoid operationImp() {
System.out.println("ConcreteImplementorA.operationImp()");
}
}
// Source code from file:ConcreteImplementorB.java
packagedesignPatterns.Bridge;
publicclass ConcreteImplementorB implements Implementor {
publicvoid operationImp() {
System.out.println("ConcreteImplementorB.operationImp()");
}
}
// Source code from file:Implementor.java
packagedesignPatterns.Bridge;
publicinterface Implementor {
publicvoid operationImp();
}
// Source code from file:RefinedAbstraction.java
packagedesignPatterns.Bridge;
publicclass RefinedAbstraction extends Abstraction {
publicRefinedAbstraction(String systemType) {
if(systemType.equals("SystemA"))
imp =new ConcreteImplementorA();
elseif (systemType.equals("SystemB"))
imp =new ConcreteImplementorB();
}
publicvoid operation() {
// do some thing
super.operation();
}
}
// Source code from file:User.java
packagedesignPatterns.Bridge;
publicclass User {
publicstatic void main(String[] args) {
Abstraction absA =new RefinedAbstraction("SystemA");
absA.operation();
Abstraction absB =new RefinedAbstraction("SystemB");
absB.operation();
}
}
[/java]