抽象與實現html
抽象不該該依賴於實現細節,實現細節應該依賴於抽象。設計模式
問題在於若是抽象B因爲固有的緣由,自己並不穩定,也有可能變化,怎麼辦?promise
舉例來講post
假如咱們須要開發一個同時支持PC和手機的坦克遊戲,遊戲在PC和手機上功能都同樣,都有一樣的類型,面臨一樣的功能需求變化,好比坦克可能有不少種不一樣的型號:T50,T75,T90……url
對於其中的坦克設計,咱們可能很容易設計出來一個Tank的抽象基類,而後各類不一樣型號的Tank繼承自該類;spa
另外的變化緣由設計
可是PC和手機上的圖形繪製、聲效、操做等實現徹底不一樣……所以對於各類型號的坦克,都要提供各類不一樣平臺上的坦克實現:3d
這樣的設計會帶來不少問題:有不少重複代碼,類的結構過於複雜,難以維護,最致命的是引入任何新平臺,好比在TV上的Tank遊戲,都會讓整個類層級結構複雜化。orm
動機(Motivation)htm
思考上述問題的癥結:事實上因爲Tank類型的固有邏輯,使得Tank類型具備了兩個變化的維度——一個變化的維度爲「平臺的變化」,一個變化的維度爲「型號的變化」。
如何應對這種「多維度的變化」?如何利用面向對象技術來使得Tank類型能夠輕鬆地沿着「平臺」和「型號」兩個方向變化,而不引入額外的複雜度?
意圖(Intent)
將抽象部分與實現部分分離,使它們均可以獨立地變化。
——《設計模式》GoF
橋模式不能只是認爲是抽象和實現的分離,它其實並不只限於此。以下面的例子,兩個都是抽象的部分。更確切的理解,應該是將一個事物中多個維度的變化分離。
對於這種在多個維度上都會有變化或擴充需求的項目來講,能夠考慮引入橋接模式。或許你會說,不論是什麼場景,無論什麼模式,均可以是抽象場景的一個子類,可是,若是這樣的話,4個場景和3種模式就會產生12個子類,而10個場景5種模式就會有50個子類。一味進行繼承並非什麼好方法,橋接模式的思想是把繼承轉化爲組合,把乘法(10*5=50)轉化爲加法(10+5=15)。
例說Bridge應用
版本一
先寫各類不一樣的坦克型號類T50、T75等繼承自Tank,而後再讓各類平臺的坦克繼承自對應型號的類,如PCT50,PCT75繼承自T50等。這樣設計可能會有不少重複的代碼,例PCT50和PCT75。
版本二
由於平臺和坦克型號都是變化,因此咱們把平臺的變化做爲屬性放到基抽象類中。
平臺實現類
下面是整個代碼的骨架
Tank的型號,和Tank的平臺都繼承自各自的抽象類,所以它們的變化都不會影響到對方。而它們之間的關聯,咱們使用組合的方式,把平臺類放到Tank類中做爲屬性。這再次體現了組合優先於繼承的思想。多繼承的方法就是版本一的代碼,這種方式子類和父類的關係太緊,形成緊耦合。
這就是橋模式,把變化引出了基類Tank,使得Tank僅守與型號的變化。
應用程序
在環境交互中使用的都是抽象類,而且把平臺實現隱藏,在應用程序中new平臺的方式也能夠根據狀況用Singleton模式或者Abstract Factory模式等實現。
結構(Structure)
其中imp的地方就是一個組合。Abstraction就是咱們以前例子中的Tank,它的子類RefinedAbstraction就是T50等型號。Implementor是TankPlatformImplementation類,ConcreteImplementorA和ConcreteImplementorB分別是PCTankImplementation和MobileTankImplementation。
整個設計模式的關鍵就是組合的使用。
Bridge模式的幾個要點
Bridge模式使用「對象間的組合關係」解耦了抽象和實現之間固有的綁定關係,使得抽象(Tank的型號)和實現(不一樣的平臺)能夠沿着格子的維度來變化。
所謂抽象和實現沿着各自維度的變化,即「子類化」它們(好比不一樣的Tank型號子類,和不一樣的平臺子類),獲得各個子類以後,即可以任意組合它們,從而得到不一樣平臺上的不一樣型號。
Bridge模式有時候相似於多繼承方案,可是多繼承方案每每違背單一職責原則(即一個類只有一個變化的緣由),複用性比較差。Bridge模式是比多繼承方案更好的解決方法。
下面是針對上面的例子,多繼承接口的一種寫法:
這樣PCT50既須要寫T50的實現,又要寫Platform的實現,它把型號和平臺的變化都引入了PCT50。這樣就把兩個本不應扭在一塊兒的事務扭在了一塊兒,這樣的設計更加糟糕,並且也違背了類的單一職責原則。
Bridge模式的應用通常在「兩個很是強的變化維度」,有時候即便有兩個變化的維度,可是某個方向的變化維度並不劇烈——換言之兩個變化不會致使縱橫交錯的結果,並不必定要使用Bridge模式。
橋模式並不一樣於適配器模式,適配器模式實際上是一個過後諸葛亮,當發現之前的東西不適用了纔去作一個彌補的措施。橋模式相對來講所作的改變比適配器模式早,它能夠適用於有兩個甚至兩個以上維度的變化。