生活随笔
收集整理的這篇文章主要介紹了
《Java设计模式》之桥接模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Bridge模式的概念
Bridge 模式是構造型的設計模式之中的一個。Bridge模式基于類的最小設計原則,通過使用封裝,聚合以及繼承等行為來讓不同的類承擔不同的責任。它的主要特點是把抽象(abstraction)與行為實現(implementation)分離開來,從而能夠保持各部分的獨立性以及應對它們的功能擴展。
Bridge模式的應用場景
面向對象的程序設計(OOP)里有類繼承(子類繼承父類)的概念,假設一個類或接口有多個詳細實現子類。假設這些子類具有下面特性:
- 存在相對并列的子類屬性。
- 存在概念上的交叉。
- 可變性。
我們就能夠用Bridge模式來對其進行抽象與詳細。對相關類進行重構。
橋接模式的適用:
你不希望在抽象和它的實現部分之間有一個固定的綁定關系。比如:程序的實現部分在執行時須要被選擇或者切換。
類的抽象以及它的實現都應該能夠通過生成子類的方法加以擴充。
這時Bridge模式使你能夠對不同的抽象接口和實現部分進行組合,并分別對它們進行擴充。
對一個抽象實現的改動須要對客戶不產生影響,即客戶的代碼不必又一次編譯。
有很多類要生成。這樣的情況下你必須將一個對象分解成兩個部分。這樣的類層次結構為“嵌套的普化”。
你想在多個對象間共享實現(可能使用引用計數),但同一時候要求客戶并不知道這一點。
生活中的一個樣例:
??? 拿汽車在路上行駛的來說。
既有小汽車又有公共汽車,它們都不但能在市區中的公路上行駛,也能在快速公路上行駛。這你會發現,對于交通工具(汽車)有不同的類型。它們所行駛的環境(路)也有不同類型,在軟件系統中就要適應兩個方面(不同車型,不同道路)的變化,如何實現才干應對這樣的變化呢?
概述:
在軟件系統中。某些類型因為自身的邏輯。它具有兩個或多個維度的變化,那么怎樣應對這樣的“多維度的變化”?怎樣利用面向對象的技術來使得該類型可以輕松的沿著多個方向進行變化,而又不引入額外的復雜度?這就要使用Bridge模式。
意圖:
將抽象部分與實現部分分離,使它們都能夠獨立的變化。
????????????????????????????????????????????????????????????????????——《設計模式》GOF?
上面這些話我也沒看懂。
。太抽象了,可是一看代碼你就明確是怎么回事了。
結構圖:
傳統的做法:
??????? 通過類繼承的方式來做上面的樣例;
先看一下類結構圖:
代碼實現:
[java]?view plaincopyprint?
?????????? class?Road?{?? ????void?run()?{?? ????????System.out.println("路");?? ????}?? }?? ?? ?? class?Street?extends?Road?{?? ????void?run()?{?? ????????System.out.println("市區街道");?? ????}?? }?? ?? ?? class?SpeedWay?extends?Road?{?? ????void?run()?{?? ????????System.out.println("快速公路");?? ????}?? }?? ?? class?CarOnStreet?extends?Street?{?? ????void?run()?{?? ????????System.out.println("小汽車在市區街道行駛");?? ????}?? }?? ?? class?CarOnSpeedWay?extends?SpeedWay?{?? ????void?run()?{?? ????????System.out.println("小汽車在快速公路行駛");?? ????}?? }?? ?? class?BusOnStreet?extends?Street?{?? ????void?run()?{?? ????????System.out.println("公交車在市區街道行駛");?? ????}?? }?? ?? class?BusOnSpeedWay?extends?SpeedWay?{?? ????void?run()?{?? ????????System.out.println("公交車在快速公路行駛");?? ????}?? }?? ?? public?static?void?main(String[]?args)?{?? ?????? ?????? ????CarOnSpeedWay?carOnSpeedWay?=?new?CarOnSpeedWay();?? ????carOnSpeedWay.run();?? ?????? ????BusOnStreet?busOnStreet?=?new?BusOnStreet();?? ????busOnStreet.run();?? ?? }?? 缺點:
???? 可是我們說這種設計是脆弱的,細致分析就能夠發現,它還是存在非常多問題,首先它在遵循開放-封閉原則的同一時候。違背了類的單一職責原則,即一個類僅僅有一個引起它變化的原因。而這里引起變化的原因卻有兩個。即路類型的變化和汽車類型的變化;其次是反復代碼會非常多,不同的汽車在不同的路上行駛也會有一部分的代碼是同樣的;
再次是類的結構過于復雜,繼承關系太多,難于維護。最后最致命的一點是擴展性太差。假設變化沿著汽車的類型和不同的道路兩個方向變化,我們會看到這個類的結構會迅速的變龐大。
應用設計模式
?????? 橋接模式(Bridge)來做;
先看一下類結構圖:
代碼實現:
[java]?view plaincopyprint?
abstract?class?AbstractRoad{?? ????AbstractCar?aCar;?? ????void?run(){};?? }?? abstract?class?AbstractCar{?? ????void?run(){};?? }?? ?? class?Street?extends?AbstractRoad{?? ????@Override?? ????void?run()?{?? ?????????? ????????super.run();?? ????????aCar.run();?? ????????System.out.println("在市區街道行駛");?? ????}?? }?? class?SpeedWay?extends?AbstractRoad{?? ????@Override?? ????void?run()?{?? ?????????? ????????super.run();?? ????????aCar.run();?? ????????System.out.println("在快速公路行駛");?? ????}?? }?? class?Car?extends?AbstractCar{?? ????@Override?? ????void?run()?{?? ?????????? ????????super.run();?? ????????System.out.print("小汽車");?? ????}?? }?? class?Bus?extends?AbstractCar{?? ????@Override?? ????void?run()?{?? ?????????? ????????super.run();?? ????????System.out.print("公交車");?? ????}?? }?? ?? public?static?void?main(String[]?args){?? ?????? ????AbstractRoad?speedWay?=?new?SpeedWay();?? ????speedWay.aCar?=?new?Car();?? ????speedWay.run();?? ?????? ????AbstractRoad?street?=?new?Street();?? ????street.aCar?=?new?Bus();?? ????street.run();?? }?? ?能夠看到。通過對象組合的方式,Bridge 模式把兩個角色之間的繼承關系改為了耦合的關系。從而使這兩者能夠從容自若的各自獨立的變化,這也是Bridge模式的本意。
??????這樣添加了客戶程序與路與汽車的耦合。
事實上這種操心是沒有必要的,由于這種耦合性是由于對象的創建所帶來的,全然能夠用創建型模式去解決。在應用時結合創建型設計模式來處理詳細的問題。
應用設計模式:
?????? 橋接模式(Bridge)來做(多維度變化);
?????? 結合上面的樣例,添加一個維度"人",不同的人開著不同的汽車在不同的路上行駛(三個維度);
???????結合上面添加一個類"人",并又一次調用.
代碼實現:
[java]?view plaincopyprint?
abstract?class?People?{?? ????AbstractRoad?road;?? ?? ????void?run()?{}?? }?? ?? class?Man?extends?People{?? ????@Override?? ????void?run()?{?? ?????????? ????????super.run();?? ????????System.out.print("男人開著");?? ????????road.run();?? ????}?? }?? class?Woman?extends?People{?? ????@Override?? ????void?run()?{?? ?????????? ????????super.run();?? ????????System.out.print("女人開著");?? ????????road.run();?? ????}?? }?? ?? public?static?void?main(String[]?args)?{?? ?? ????AbstractRoad?speedWay?=?new?SpeedWay();?? ????speedWay.aCar?=?new?Car();?? ?????? ????People?man?=?new?Man();?? ????man.road?=?speedWay;?? ????man.run();?? }??
效果及實現要點:
1.Bridge模式使用“對象間的組合關系”解耦了抽象和實現之間固有的綁定關系,使得抽象和實現能夠沿著各自的維度來變化。
2.所謂抽象和實現沿著各自維度的變化,即“子類化”它們。得到各個子類之后,便能夠隨意它們。從而獲得不同路上的不同汽車。
3.Bridge模式有時候類似于多繼承方案,可是多繼承方案往往違背了類的單一職責原則(即一個類僅僅有一個變化的原因),復用性比較差。Bridge模式是比多繼承方案更好的解決方法。
4.Bridge模式的應用一般在“兩個很強的變化維度”,有時候即使有兩個變化的維度。可是某個方向的變化維度并不劇烈——換言之兩個變化不會導致縱橫交錯的結果,并不一定要使用Bridge模式。
適用性:
?? 在下面的情況下應當使用橋梁模式:
1.假設一個系統須要在構件的抽象化角色和詳細化角色之間添加很多其它的靈活性,避免在兩個層次之間建立靜態的聯系。?
2.設計要求實現化角色的不論什么改變不應當影響client,或者說實現化角色的改變對client是全然透明的。
3.一個構件有多于一個的抽象化角色和實現化角色。系統須要它們之間進行動態耦合。?
4.盡管在系統中使用繼承是沒有問題的。可是因為抽象化角色和詳細化角色須要獨立變化,設計要求須要獨立管理這兩者。
總結:
??????Bridge模式是一個很實用的模式,也很復雜。它很好的符合了開放-封閉原則和優先使用對象,而不是繼承這兩個面向對象原則。
?
本文借鑒文章:
http://blog.csdn.net/jason0539/article/details/22568865
總結
以上是生活随笔為你收集整理的《Java设计模式》之桥接模式的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。