橋接模式

介紹

橋接模式(Bridge Pattern) 也稱為橋梁模式,是結(jié)構(gòu)型設(shè)計(jì)模式之一。橋接模式的作用就是連接 "兩邊"

定義

將抽象部分與實(shí)現(xiàn)部分分離,使他們都可以獨(dú)立地進(jìn)行變化

定義看起來跟橋接沒有一毛錢關(guān)系,但是別著急,慢慢往下看。

使用場景

先舉個例子,要不 抽象部分實(shí)現(xiàn)部分 真的會亂。

比如去星巴克買的咖啡(媽蛋,不知道誰買,反正我是一杯都買不起),最簡單的,分大杯小杯,這里的大杯小杯就是咖啡的一個維度。再分還有加糖不加糖,這里的加糖不加糖又是咖啡這個東西的一個維度。

大小杯跟是否加糖是兩個互不影響相互獨(dú)立的維度。

如果我們把咖啡定義為一個抽象類,大杯咖啡或者小杯咖啡分別為具體實(shí)現(xiàn)類,那么,加糖不加糖這個維度怎么處理?我們可能會想到,繼續(xù)繼承大杯或者小杯,然后分別定義不同的加糖不加糖的類,瞬間,兩個實(shí)現(xiàn)類就變成了四個,如果這時候我們增加了中杯,那么就需要再多加三個類。這還簡單,如果這時候我們又加了糖分度,這時候繼承類的數(shù)量會瞬間爆炸,所以繼承不能解決問題。

既然繼承不能解決問題,那我們還有沒有別的辦法? 當(dāng)然有,今天這個橋接模式解決的就是這類的問題。

以加糖不加糖為例,我們把加糖不加糖這個維度抽象出一個接口,并且在咖啡類里面保持對一個加糖不加糖接口的引用,在咖啡類的構(gòu)造方法中我們需要傳入是否加糖這個對象,為接口對象賦值,并在咖啡類中用到是否加糖的方法時,調(diào)用是否需要加糖這個引用的方法。

這樣就把是否加糖這個維度和大杯小杯這個維度分離開來,當(dāng)大小杯變化比如增加中杯,加糖不加糖變化比如增加低度糖,這兩個變化就不會耦合在一起,可以獨(dú)立改變。

這里的咖啡以及大小杯的咖啡子類就是抽象部分,加糖不加糖就是實(shí)現(xiàn)部分。這個如果不理解就先記住

使用場景

  • 從模式的定義中我們大致了解到,這里的 “橋梁” 的作用就是連接 “抽象部分” 與 “實(shí)現(xiàn)部分” ,但是事實(shí)上,任何多維度變化類或者說多個樹狀類之間的耦合都可以使用橋接模式來實(shí)現(xiàn)解耦。

  • 如果一個系統(tǒng)需要在構(gòu)件的抽象化角色和具體化角色之間增加更多靈活性,避免在這兩個層次之間建立靜態(tài)的繼承聯(lián)系,可以通過橋接模式使它們在抽象層建立一個關(guān)聯(lián)關(guān)系。

  • 對于那些不希望使用繼承或因?yàn)槎鄬永^承導(dǎo)致系統(tǒng)類的個數(shù)急劇增加的系統(tǒng),也可以考慮使用橋接模式

  • 一個類存在兩個獨(dú)立變化的維度,且這兩個維度都需要進(jìn)行擴(kuò)展

前面例子中的加糖和大小杯就是兩個維度,我們不希望通過分層繼承的方式解決,所以使用橋接模式

角色介紹

  • Abstraction 抽象部分,該類保持一個對實(shí)現(xiàn)部分對象的引用,抽象部分中的方法需要調(diào)用實(shí)現(xiàn)部分的對象的相關(guān)方法來實(shí)現(xiàn),該類一般為一個抽象類

  • RefinedAbstraction 優(yōu)化的抽象部分,抽象部分的具體實(shí)現(xiàn),該類一般是對抽象部分的方法進(jìn)行完善和擴(kuò)展

  • Implementor 實(shí)現(xiàn)部分,可以為接口或者抽象類,其方法不一定要與抽象部分中的一致,一般情況下是由實(shí)現(xiàn)部分提供基本的操作,而抽象部分定義的則是基于實(shí)現(xiàn)部分這些基本操作的業(yè)務(wù)方法。

  • ConcreteImplementorA/ConcreteImolementorB 實(shí)現(xiàn)部分的具體實(shí)現(xiàn)

  • Client 客戶類,構(gòu)建實(shí)現(xiàn)部分的對象,根據(jù)實(shí)現(xiàn)部分的對象構(gòu)建抽象部分的對象,最后調(diào)用抽象部分的方法完成業(yè)務(wù)。

Android 源碼中的橋接模式

在 View 的視圖層中的應(yīng)用

在 View 的視圖層級中,CheckBox、CompoundButton、Button、TextView、View 之間過程了一個繼承關(guān)系層,每一層都是對一種類型控件的描述,其定義了該類所擁有的的基本屬性和行為。但是將他們真正繪制到屏幕上的部分是由與 View 相關(guān)的 DisplayList、Canvas 等硬件繪制部分負(fù)責(zé),繪制這部分就是另一個維度,這兩部分的關(guān)系可以看做是對橋接模式的應(yīng)用。

解釋一下:這里的抽象部分就是這些 View 的繼承關(guān)系層,不同的行為是一個維度,但是繪制的過程則是由 Canvas 等來實(shí)現(xiàn)的,繪制則是另一個維度,相當(dāng)于實(shí)現(xiàn)部分。兩個部分是不耦合的。

Adapter 與 AdapterView 直接的關(guān)系

Adapter 與 AdapterView 也可以看做是橋接模式,AdapterView 的具體功能是一個維度,而獲取每個 item 顯示的內(nèi)容可以看做是另一個維度,這時候 AdapterView 是抽象部分,Adapter 則是實(shí)現(xiàn)部分。抽象與實(shí)現(xiàn)不耦合。

橋接模式實(shí)戰(zhàn)

自定義一個進(jìn)度條,有水平的,豎直的,圓形的三種。那么繪制方式也就是有三種,我么此時可以將具體的繪制邏輯作為一個維度來提取出來,也就是定義一個抽象的進(jìn)度條類,其中的抽象方法為繪制一個 View 所需的最少的成員屬性,再定義這個抽象進(jìn)度條的三個子類,這三個子類分別完成三種不同形狀進(jìn)度條的繪制。注意,這里的進(jìn)度條繪制類并不是一個 View,只是實(shí)現(xiàn)了繪制的具體實(shí)現(xiàn)

在自定義的在 View 類中,持有對繪制類的對象引用,根據(jù)想要的進(jìn)度條來實(shí)例繪制類的對象,在 view 的真正繪制方法中調(diào)用繪制類的對象的方法來實(shí)現(xiàn)。

此時,自定義的 View 類就是橋接模式的抽象部分,而繪制的部分就是實(shí)現(xiàn)部分。

其他實(shí)現(xiàn)

  1. 數(shù)據(jù)庫 dao 類的設(shè)計(jì)有時會使用橋接模式,如果對數(shù)據(jù)庫的一個訪問有不同的方式,這時候就可以把訪問方式作為一個維度來處理

  2. Android 應(yīng)用層和 Native 層之間的交互也是橋接模式,在操縱硬件設(shè)備時就使用一個連接應(yīng)用層與 Native 層的橋梁,這個橋梁通常是一個具體的類,比如提供操作相機(jī)的 Camera,播放音視頻的 MediaPlayer、提供圖形繪制接口的 OpenCV 等,這些 API 類為我們操作底層硬件提供了可能

總結(jié)

橋接模式可以應(yīng)用到許多開發(fā)中,但是應(yīng)用的并不多,一個很主要的原因是對于抽象與實(shí)現(xiàn)分離的把握,是不是需要分離,如何分離?對于設(shè)計(jì)者來說要有一個恰到好處的分寸。

優(yōu)點(diǎn)

分離抽象與實(shí)現(xiàn),靈活的擴(kuò)展以及對客戶來說透明的實(shí)現(xiàn)。

缺點(diǎn)

分離的分寸不容易把握

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在正式介紹橋接模式之前,我先跟大家談?wù)剝煞N常見文具的區(qū)別,它們是毛筆和蠟筆。假如我們需要大中小3種型號的畫筆,能夠...
    justCode_閱讀 1,858評論 0 7
  • 1 場景問題# 1.1 發(fā)送提示消息## 考慮這樣一個實(shí)際的業(yè)務(wù)功能:發(fā)送提示消息。基本上所有帶業(yè)務(wù)流程處理的系統(tǒng)...
    七寸知架構(gòu)閱讀 5,217評論 5 63
  • 本文參考:http://www.oschina.net/question/1436074_140456 http:...
    端木軒閱讀 3,659評論 0 5
  • Bridge Pattern,是結(jié)構(gòu)型設(shè)計(jì)模式之一, 定義: 將抽象部分與實(shí)現(xiàn)部分分離,使得他們可以獨(dú)立的進(jìn)行變化...
    Alexey閱讀 741評論 0 2
  • 養(yǎng)狗這事我妹已經(jīng)纏著我說了好久,而且她要養(yǎng)柯基,都以我否決告終。我的理由很充分:1. 養(yǎng)了你就要對它負(fù)責(zé)。2. 柯...
    愛麗是松兒閱讀 1,793評論 0 0

友情鏈接更多精彩內(nèi)容