1,為什麼要使用橋接設計模式
我們先來說說在電腦硬體中的整合元件和獨立元件之間的區別,先說說整合元件吧.
主機箱有一個叫主板的玩意,是用來插接各種不同的元件的,例如(音效卡,顯卡,硬碟等).然後協調這些元件進行工作.
其實最早電腦都是整合元件,也就是說主板上面不能進行插接更換元件,用的都是整合的顯卡音效卡等,耦合性是很高,如果用UML表示就是
總結一下這種設計模式有什麼壞處:
a,如果我們去添加一種主板,例如微星的主板,那麼就要單獨為這種主板去建立微星主板整合顯卡和微星主板整合音效卡,再添加昂達主板的話與剛才所述一樣,那麼這個結構就會是一個龐然大物.
b,如果我們修改華碩主板類那麼它下面的子類(華碩主板整合顯卡和華碩主板整合音效卡)都會受到影響.
那麼有什麼方法可以降低這樣設計的耦合,這裡我們得提一個設計原則叫做,合成/彙總設計原則,原意是我們優先考慮合成/彙總方式再考慮繼承方式.那什麼是合成/彙總呢
這裡大雁與雁群就是彙總關係,翅膀和大雁的關係就是合成關係.彙總關係體現了一種弱的耦合關係,彙總類(雁群)不一定要擁有被彙總類(大雁)的對象.而合成關係則體現了一種較
強的耦合關係,合成類(大雁)一定要擁有被合成類(翅膀)的對象.
那麼我們按照剛才的合成/彙總設計原則就可以解耦了.主板和元件之間就是一種彙總關係.
2,什麼橋接設計模式
橋接設計模式就是利用合成/彙總設計原則,使抽象部分與實現部分分離,使它們都能夠獨立的變化.
就剛才的執行個體,抽象部分就是主板,而實現部分就是元件了.
3,怎麼使用橋接設計模式
我們按照橋接設計模式修改後那麼UML就如下
這樣的設計模式分離了抽象部分與實現部分,其實也就是主板和元件的分離,使其添加主板或者音效卡互不影響,而且不會是子類成倍擴張,修改主板類也不會影響到元件類,彌補了之前提到的a,b亮點的不足.而且還遵從了開放-封閉設計原則.
最後原始碼如下:
主板.class
public abstract class 主板 {private 音效卡 shengka = null;private 顯卡 xianka = null;public void 裝載音效卡(音效卡 yuanjian){shengka = yuanjian;}public void 裝載顯卡(顯卡 yuanjian){xianka = yuanjian;}public void 運行音效卡(){if(shengka == null){System.out.println("請先裝載音效卡.");return;}shengka.運行元件();}public void 運行顯卡(){if(xianka == null){System.out.println("請先裝載顯卡.");return;}xianka.運行元件();}//由於具體的主板運行方式不一樣,所以留給子類去實現public abstract void 運行主板();}
元件.class
public abstract class 元件 {public abstract void 運行元件();}
華碩主板.class
public class 華碩主板 extends 主板{@Overridepublic void 運行主板() {// TODO Auto-generated method stubSystem.out.print("在華碩主板上\n");this.運行音效卡();this.運行顯卡();}}
微星主板.class
public class 微星主板 extends 主板{@Overridepublic void 運行主板() {// TODO Auto-generated method stubSystem.out.print("在微星主板上\n");this.運行音效卡();this.運行顯卡();}}
音效卡.class
public class 音效卡 extends 元件{@Overridepublic void 運行元件() {// TODO Auto-generated method stubSystem.out.println("運行音效卡");}}
顯卡.class
public class 顯卡 extends 元件{@Overridepublic void 運行元件() {// TODO Auto-generated method stubSystem.out.println("運行顯卡");}}
Main.class
public class Main {public static void main(String [] args){主板 zhuban1 = new 華碩主板();zhuban1.裝載音效卡(new 音效卡());zhuban1.裝載顯卡(new 顯卡());zhuban1.運行主板();主板 zhuban2 = new 微星主板();zhuban2.裝載音效卡(new 音效卡());zhuban2.裝載顯卡(new 顯卡());zhuban2.運行主板();}}
最後輸出:
在華碩主板上
運行音效卡
運行顯卡
在微星主板上
運行音效卡
運行顯卡