什麼是橋接模式
從字面意思看,“橋接”就是用橋去連接的意思,橋建好後,橋兩邊的世界就可以相互來往了。
歲月更迭,橋本身不會有變化,但是橋兩邊的世界有無窮的變化,而且,兩邊的變化彼此獨立,互不影響。
就像“燈、電線、開關”這樣的實際生活場景,電線就是橋,燈和開關就是橋兩邊的世界,通過電線把燈和開關連接起來工作,這就是橋接模式。
燈壞了換燈,開關壞了換開關,而且,想換什麼樣的就換什麼樣的,換燈的時候不用考慮開關,換開關的時候不用考慮燈,操作起來能這麼方便,全都是電線的功勞。
這也就是橋接模式的好處:
通過一座橋,解藕橋兩邊系統的強關聯性,讓它們能夠獨立的變化
試想一下,如果沒有電線,直接把開關集成在燈上面,那麼,燈和開關任何一個出現問題,兩者就都得換,並且,兩者緊緊的綁在一起,誰也別想離開誰,不離不棄,生死相依,這就是愛情的模樣吧。
生活需要愛情,系統需要自由,玫瑰香水給你甜蜜的愛情,橋接模式給你想要的自由~~
設計與實現
現實生活中,橋能看得見,很好理解,但在編程中,橋是個抽象的概念,並不是一個具體的東西,相對來說,可能會不太好理解。
其實橋接模式很簡單,就是編碼的時候,抽象與實現分離,靈活運用多態。這也是很多設計模式的精髓所在。
還拿燈和開關舉例子,先看看不用橋接模式的話,應該如何設計:
// 一個正常的燈
public class NormalLamp {
public void powerOn() {
System.out.println("開始工作");
}
public void powerOff() {
System.out.println("停止工作");
}
}
// 一個正常的開關
public class NormalSwitch {
private NormalLamp lamp;
public NormalSwitch(NormalLamp lamp) {
this.lamp = lamp;
}
public void turnOn() {
lamp.powerOn();
}
public void turnOff() {
lamp.powerOff();
}
}
// 測試方法
public static void main(String[] args) {
NormalLamp normalLamp = new NormalLamp();
NormalSwitch normalSwitch = new NormalSwitch(normalLamp);
normalSwitch.turnOn();// 開
normalSwitch.turnOff();// 關
}
稍微有點編程經驗的人,可能都會看出來,這樣的編碼風格耦合性太強,燈NormalLamp
和開關NormalSwitch
強關聯,換燈就必須換開關。
比如,想換個高級燈AdvancedLamp
,就必須加個高級開關AdvancedSwitch
,因爲普通開關NormalSwitch
不支持高級燈的工作。
把這段代碼用橋接模式重新設計,體現出抽象和多態的思想:
// 燈的抽象
public interface Lamp {
void powerOn();
void powerOff();
}
// 普通的燈
public class NormalLamp implements Lamp {
@Override
public void powerOn() {
System.out.println("開始工作");
}
@Override
public void powerOff() {
System.out.println("停止工作");
}
}
// 高級的燈
public class AdvancedLamp implements Lamp {
@Override
public void powerOn() {
System.out.println("高級燈開始工作");
}
@Override
public void powerOff() {
System.out.println("高級燈停止工作");
}
}
// 普通的開關
public class NormalSwitch {
private Lamp lamp;
public NormalSwitch(Lamp lamp) {
this.lamp = lamp;
}
@Override
public void turnOn() {
lamp.powerOn();
}
@Override
public void turnOff() {
lamp.powerOff();
}
}
// 測試方法
public static void main(String[] args) {
NormalLamp normalLamp = new NormalLamp();
NormalSwitch normalSwitch = new NormalSwitch(normalLamp);
normalSwitch.turnOn();
normalSwitch.turnOff();
// 換高級燈
AdvancedLamp advancedLamp = new AdvancedLamp();
normalSwitch = new NormalSwitch(advancedLamp);
normalSwitch.turnOn();
normalSwitch.turnOff();
}
這段代碼對燈進行了抽象,普通開關NormalSwitch
內部連接着燈的抽象Lamp
,這個連接就是橋,這種編碼方法就是橋接模式。
可以說,現在的普通開關NormalSwitch
特別厲害,它能控制所有的燈工作,只需要給它一個具體的燈對象就好。
現在,開關不變,燈可以隨便換。
再進一步,如果開關也想多樣化,也要自由的更換,那就再對開關也進行一個抽象,運用上多態思想:
// 開關的抽象
public abstract class Switch {
private Lamp lamp;
public Switch(Lamp lamp) {
this.lamp = lamp;
}
public void turnOn() {
lamp.powerOn();
}
public void turnOff() {
lamp.powerOff();
}
}
// 普通開關
public class NormalSwitch extends Switch {
public NormalSwitch(Lamp lamp) {
super(lamp);
}
}
// 高級開關
public class AdvancedSwitch extends Switch {
public AdvancedSwitch(Lamp lamp) {
super(lamp);
}
}
設計到這裏,燈和開關就都能自由的更換組合了。
總結
橋接模式的核心是抽象與實現的分離,運用多態機制達到運行時的多樣化效果。
本文的橋接模式只涉及到兩個維度的變量,燈和開關,如果業務場景複雜,也可能有多個變量維度。
橋接模式是設計模式裏面很基礎的一種,體現的主要是面嚮對象語言的兩大特性:封裝、多態。
設計模式,萬變不離其宗:抽象與實現的分離