大话设计模式—桥接模式
橋接(Bridge)是用于把抽象化與實現化解耦,使得二者可以獨立變化。這種類型的設計模式屬于結構型模式,它通過提供抽象化和實現化之間的橋接結構,來實現二者的解耦。主要解決:在有多種可能會變化的情況下,用繼承會造成類爆炸問題,擴展起來不靈活。這種模式涉及到一個作為橋接的接口,使得實體類的功能獨立于接口實現類。這兩種類型的類可被結構化改變而互不影響。
大話設計模式中程杰老師給出的定義是,橋接模式:將抽象部分與實現部分分離,使它們都可以獨立的變化。
首先我們來看一個問題:現在我有一個N品牌一個M品牌的手機,兩個品牌的手機都有兩種功能:游戲和通訊錄,我們該如何實現?
依據面向對象的理論設計,我們有兩種設計思想:
實現一:先有一個品牌,多個品牌就抽象出一個品牌抽象類,對于每個功能,就都繼承各自的品牌;
實現二:先有功能,多個功能就可以抽象出一個抽象功能類,對于每個手機品牌,分別去繼承各個功能;
上面的設計完美的遵循了面向對象的原則,但是,問題也隨之而來,如果我現在需要給每個品牌都增加一個MP3播放器功能,我們該怎么辦?
對于實現一,我們需要在每個品牌下面分別增加一個MP3播放器功能;對于實現二,我們需要在手機軟件下增加一個抽象的MP3播放器功能,然后各個手機品牌再分別去繼承這個功能。
如果我們需要再增加一個手機品牌呢?那我們要改動的地方就越來越多了。顯然這種設計似乎有問題的。
但我們學會使用面向對象的繼承時,確實感覺它非常強大,但是并不是所有的情況都可以使用面向對象的繼承,而且有很多情況下,使用繼承會帶來麻煩。比如,對象的繼承關系是在編譯時就定義好了,所以無法在運行時改變從父類繼承的實現。子類實現與它的父類有非常緊密的依賴關系,以至于父類實現中的任何變化都必然會導致子類發生變化。當你需要復用子類時,如果繼承下來的實現不適合解決新的問題,則父類必須重寫或被其它更適合的類替換。這種依賴關系限制了靈活性并最終限制了復用性。
就像我們上面的兩種實現,如果不斷地增加新的手機品牌和功能,類會越來越多。怎么解決呢?面向對象設計中還有一個很重要的原則合成/聚合復用原則,即優先使用對象合成/聚合,而不是類繼承。
合成表示一種強的擁有關系,體現了嚴格的部分和整體的關系,部分和整體的生命周期一樣,打個比方:人有兩個胳膊,胳膊和人就是部分和整體的關系,人去世了,那么胳膊也就沒用了,也就是說胳膊和人的生命周期是相同的,合成關系用實心的菱形+實線來表示。
合成/聚合復用規則的好處:優先使用對象的合成/聚合將有助于你保持每個類被封裝,并被集中在單個任務上。這樣類和類繼承層次會保持在一個較小的規模,并且不太可能增長為不可控制的龐然大物。
下面我么來看看遵循合成/聚合復用規則的實現三:
橋接模式的核心意圖就是把這些實現獨立出來,讓它們各自的變化。這就使得每種實現的變化不會影響其它的實現,從而達到應對變化的目的。
代碼實現:
package com.bridge;public abstract class Implementor {public abstract void operation();} package com.bridge;public class ConcreteImplementorA extends Implementor {@Overridepublic void operation() {System.out.println("具體實現A執行");}} package com.bridge;public class ConcreteImplementorB extends Implementor {@Overridepublic void operation() {System.out.println("具體實現B執行");}} package com.bridge;public abstract class Abstraction {protected Implementor implementor;public void setImplementor(Implementor implementor){this.implementor = implementor;}public void operation(){implementor.operation();}} package com.bridge;public class RefinedAbstraction extends Abstraction {public void operation(){implementor.operation();}} package com.bridge;public class BridgePatternDemo {public static void main(String[] args) {Abstraction ab = new RefinedAbstraction();ab.setImplementor(new ConcreteImplementorA());ab.operation();ab.setImplementor(new ConcreteImplementorB());ab.operation();}}運行結果:
具體實現A執行 具體實現B執行應用實例: 墻上的開關,可以看到的開關是抽象的,不用管里面具體怎么實現的。
優點:
1、抽象和實現的分離。
2、優秀的擴展能力。
3、實現細節對客戶透明。
缺點:
橋接模式的引入會增加系統的理解與設計難度,由于聚合關聯關系建立在抽象層,要求開發者針對抽象進行設計與編程。
使用場景:
1、如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承聯系,通過橋接模式可以使它們在抽象層建立一個關聯關系。
2、對于那些不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加的系統,橋接模式尤為適用。
3、一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展,對于兩個獨立變化的維度,使用橋接模式再適合不過了。
總結
以上是生活随笔為你收集整理的大话设计模式—桥接模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大话设计模式—组合模式
- 下一篇: 大话设计模式—命令模式