1 概述
上一篇文章介紹了外觀模式,接下來介紹橋接模式。橋接模式有時也被稱爲橋樑模式,也是一種常見結構模式,它主要體現了面向對象設計中的兩個思想:
- 面向接口編程。
- 合成複用原則,即組合優先於繼承。
2 橋接模式
橋接模式的目的是將抽象與實現分離,使二者能獨立變化。說白了,其實就是:
- 給對象定義接口,來充當橋樑的作用。
- 調用者要依賴於目標對象的抽象(接口)而不是具體實現,更不是繼承目標對象。
3 案例
開發者都有自己喜歡的IDE
,比如有人喜歡用Intellij
,有人喜歡用Eclipse
,其實這就涉及到兩個維度:Developer
和IDE
,他們之間的變化是獨立的,如何最好地表示它們之間的關係?如果用繼承關係來做的話,那需要爲每一個Developer
和IDE
的組合創建一個對象,比如JavaDeveloperWithEclipse
,JavaDeveloperWithIntellij
,顯然這樣做會大大增加系統複雜度。而如果用橋接模式來維護Developer
與IDE
的關係,將會變得簡單很多:
public class Test {
public static void main(String[] args) {
// Developer與IDE的組合,完全由客戶端來決定
IDE Intellij = new Intellij();
Developer nightfield = new JavaDeveloper(Intellij);
nightfield.coding();
IDE vim = new Vim();
Developer rocky = new JavaDeveloper(vim);
rocky.coding();
IDE vsCode = new VSCode();
Developer daisy = new PythonDeveloper(vsCode);
daisy.coding();
}
}
// 充當橋樑作用的接口
public interface IDE {
void run();
}
public class Intellij implements IDE {
@Override
public void run() { System.out.println("Intellij is running..."); }
}
public class Vim implements IDE {
@Override
public void run() { System.out.println("Vim is running..."); }
}
public class VSCode implements IDE {
@Override
public void run() { System.out.println("VSCode is running..."); }
}
// Developer只依賴於IDE接口而不關心其實現
public abstract class Developer {
// 組合關係,持有IDE的實例,而且只依賴於IDE的接口而不是實現
protected IDE ide;
// 強制在構造方法中傳入IDE的實例
Developer(IDE ide) {
this.ide = ide;
}
abstract void coding();
}
public class JavaDeveloper extends Developer {
JavaDeveloper(IDE ide) {
super(ide);
}
void coding() {
ide.run();
System.out.println("Java developer is coding...");
};
}
public class PythonDeveloper extends Developer {
PythonDeveloper(IDE ide) {
super(ide);
}
void coding() {
ide.run();
System.out.println("Python developer is coding...");
};
}
輸出:
Intellij is running...
Java developer is coding...
Vim is running...
Java developer is coding...
VSCode is running...
Python developer is coding...
這個例子中的橋樑,就是IDE
接口。所謂抽象與實現分離,體現在Developer
與IDE
是組合關係,而且只依賴於IDE
接口而不依賴於它的實現,耦合度低,使得Developer
和IDE
可以獨立變化。可以遇見,無論之後對模塊做什麼修改,或者模塊增加另外的實現,都不會影響到其他的模塊。
我們熟悉的JDBC
中,就運用了橋接模式。DriverManager
代表了橋樑中的JDK
一端,Driver
的實現(如OracleDriver
)代表了橋樑的數據庫供應商一端,而Driver
接口充當了橋樑的角色,JDK
可是要“兼容”所有的數據庫的,纔不關心Driver
的連接細節呢。
4 總結
橋接模式的核心思想是面向接口編程,組合優先於繼承。合理運用橋接模式,可以降低類之間的耦合度,從而降低系統的複雜度,提供可維護性。