21耙考、橋接模式(Bridge Pattern)

1. 橋接模式

1.1 簡(jiǎn)介

??Bridge 模式將抽象和行為劃分開,各自可以獨(dú)立地變化潭兽,但又能動(dòng)態(tài)的結(jié)合倦始。它是一種對(duì)象結(jié)構(gòu)型模式,又稱為柄體(Handle and Body)模式或接口(Interface)模式山卦。

??將抽象部分與它的實(shí)現(xiàn)部分分離鞋邑,使他們都可以獨(dú)立地變化。“將抽象部分與它的實(shí)現(xiàn)部分分離”指實(shí)現(xiàn)系統(tǒng)可能有多個(gè)角度分類枚碗,每一種分類都可能變化逾一,那么就把這種多角度分離出來讓它們獨(dú)立變化,減少它們之間的耦合肮雨。

1.2 誕生背景

??如果有一個(gè)需求遵堵,需要?jiǎng)?chuàng)建不同的圖形,并且每個(gè)圖形都有可能會(huì)有不同的顏色怨规。我們可以利用繼承的方式來設(shè)計(jì)類的關(guān)系:

圖形繼承實(shí)現(xiàn).png

??我們發(fā)現(xiàn)繼承會(huì)衍生出很多的類陌宿,假如我們?cè)僭黾右粋€(gè)形狀或再增加一種顏色,就需要?jiǎng)?chuàng)建更多的類波丰。

??試想限番,在一個(gè)有多種可能會(huì)變化的維度的系統(tǒng)中,用繼承方式會(huì)造成類爆炸呀舔,擴(kuò)展起來不靈活。每次在一個(gè)維度上新增一個(gè)具體實(shí)現(xiàn)都要增加多個(gè)子類扩灯。為了更加靈活的設(shè)計(jì)系統(tǒng)媚赖,我們此時(shí)可以考慮使用橋接模式。

1.3 橋接模式結(jié)構(gòu)

橋接模式uml:

橋接模式uml.png

橋接模式角色:

  • Abstraction(抽象類):用于定義抽象類的接口珠插,它一般是抽象類而不是接口惧磺,其中定義了一個(gè)Implementor(實(shí)現(xiàn)類接口)類型的對(duì)象并可以維護(hù)該對(duì)象,它與Implementor之間具有關(guān)聯(lián)關(guān)系捻撑,它既可以包含抽象業(yè)務(wù)方法磨隘,也可以包含具體業(yè)務(wù)方法。

  • RefinedAbstraction(擴(kuò)充抽象類):擴(kuò)充由Abstraction定義的接口顾患,通常情況下它不再是抽象類而是具體類番捂,它實(shí)現(xiàn)了在Abstraction中聲明的抽象業(yè)務(wù)方法,在RefinedAbstraction中可以調(diào)用在Implementor中定義的業(yè)務(wù)方法江解。

  • Implementor(實(shí)現(xiàn)類接口):定義實(shí)現(xiàn)類的接口设预,這個(gè)接口不一定要與Abstraction的接口完全一致,事實(shí)上這兩個(gè)接口可以完全不同犁河,一般而言鳖枕,Implementor接口僅提供基本操作,而Abstraction定義的接口可能會(huì)做更多更復(fù)雜的操作桨螺。Implementor接口對(duì)這些基本操作進(jìn)行了聲明宾符,而具體實(shí)現(xiàn)交給其子類。通過關(guān)聯(lián)關(guān)系灭翔,在Abstraction中不僅擁有自己的方法魏烫,還可以調(diào)用到Implementor中定義的方法,使用關(guān)聯(lián)關(guān)系來替代繼承關(guān)系。

  • ConcreteImplementor(具體實(shí)現(xiàn)類):具體實(shí)現(xiàn)Implementor接口则奥,在不同的ConcreteImplementor中提供基本操作的不同實(shí)現(xiàn)考润,在程序運(yùn)行時(shí),ConcreteImplementor對(duì)象將替換其父類對(duì)象读处,提供給抽象類具體的業(yè)務(wù)操作方法糊治。

2. 示例

??使用橋接模式時(shí),我們把抽象共同部分和行為共同部分各自獨(dú)立開來罚舱,原來是準(zhǔn)備放在一個(gè)接口里井辜,現(xiàn)在需要設(shè)計(jì)兩個(gè)接口:抽象接口和行為接口,分別放置抽象和行為管闷。

??以一杯咖啡為例粥脚,子類實(shí)現(xiàn)類為四個(gè):中杯加奶、大杯加奶包个、 中杯不加奶刷允、大杯不加奶。上面四個(gè)子類中有概念重疊碧囊,可從另外一個(gè)角度進(jìn)行考慮树灶,這四個(gè)類實(shí)際是兩個(gè)角色的組合:抽象 和行為,其中抽象為:中杯和大杯糯而;行為為:加奶 不加奶(如加橙汁 加蘋果汁)天通。

??實(shí)現(xiàn)四個(gè)子類在抽象和行為之間發(fā)生了固定的綁定關(guān)系,如果以后動(dòng)態(tài)增加加葡萄汁的行為熄驼,就必須再增加兩個(gè)類:中杯加葡萄汁和大杯加葡萄汁像寒。顯然混亂,擴(kuò)展性極差。那我們從分離抽象和行為的角度瓜贾,使用Bridge模式來實(shí)現(xiàn)诺祸。

行為部分:
是否加奶或其他配料的行為接口,CoffeeImp:

public interface CoffeeImp
{
   public void pourCoffeeImp();
}

加奶MilkCoffeeImp:

public class MilkCoffeeImp implements CoffeeImp
{
   public void pourCoffeeImp()
   {
     System.out.println("加了美味的牛奶");
   }
}

不加奶FragrantCoffeeImp:

public class FragrantCoffeeImp implements CoffeeImp
{
   public void pourCoffeeImp()
   {
     System.out.println("什么也沒加,清香");
   }
}

對(duì)象抽象部分:
咖啡大小杯型號(hào)抽象Coffee:

public abstract class Coffee
{
   CoffeeImp coffeeImp;
   public void setCoffeeImp(CoffeeImp coffeeImp) {
     this.CoffeeImp = coffeeImp;
   }

  public CoffeeImp getCoffeeImp() {return this.CoffeeImp;}
   public abstract void pourCoffee();
}

中杯咖啡MediumCoffee:

public class MediumCoffee extends Coffee
{
   public MediumCoffee() {setCoffeeImp();}
   public void pourCoffee()
   {
     CoffeeImp coffeeImp = this.getCoffeeImp();
     //我們以重復(fù)次數(shù)來說明是沖中杯還是大杯 ,重復(fù)2次是中杯
     for (int i = 0; i < 2; i++)
     {
      coffeeImp.pourCoffeeImp();
    }  
   }
}

大杯咖啡SuperSizeCoffee:

public class SuperSizeCoffee extends Coffee
{
   public SuperSizeCoffee() {setCoffeeImp();}
   public void pourCoffee()
   {
     CoffeeImp coffeeImp = this.getCoffeeImp();
     //我們以重復(fù)次數(shù)來說明是沖中杯還是大杯 ,重復(fù)5次是大杯
     for (int i = 0; i < 5; i++)
     {
      coffeeImp.pourCoffeeImp();
    }  
   }
}

調(diào)用示例:

    public static void main(String[] args) {  
        // 大杯加奶咖啡
        CoffeeImp milk = new MilkCoffeeImp();
        Coffee superSizeCoffee = new SuperSizeCoffee(milk);
        superSizeCoffee.pourCoffee;
    } 

3. 總結(jié)

??橋接模式是設(shè)計(jì)Java虛擬機(jī)和實(shí)現(xiàn)JDBC等驅(qū)動(dòng)程序的核心模式之一,應(yīng)用較為廣泛祭芦。在軟件開發(fā)中如果一個(gè)類或一個(gè)系統(tǒng)有多個(gè)變化維度時(shí)序臂,都可以嘗試使用橋接模式對(duì)其進(jìn)行設(shè)計(jì)。橋接模式為多維度變化的系統(tǒng)提供了一套完整的解決方案实束,并且降低了系統(tǒng)的復(fù)雜度奥秆。

橋接模式優(yōu)點(diǎn):

  • 分離抽象接口及其實(shí)現(xiàn)部分。橋接模式使用“對(duì)象間的關(guān)聯(lián)關(guān)系”解耦了抽象和實(shí)現(xiàn)之間固有的綁定關(guān)系咸灿,使得抽象和實(shí)現(xiàn)可以沿著各自的維度來變化构订。所謂抽象和實(shí)現(xiàn)沿著各自維度的變化,也就是說抽象和實(shí)現(xiàn)不再在同一個(gè)繼承層次結(jié)構(gòu)中避矢,而是“子類化”它們悼瘾,使它們各自都具有自己的子類囊榜,以便任何組合子類,從而獲得多維度組合對(duì)象亥宿。

  • 在很多情況下卸勺,橋接模式可以取代多層繼承方案,多層繼承方案違背了“單一職責(zé)原則”烫扼,復(fù)用性較差曙求,且類的個(gè)數(shù)非常多,橋接模式是比多層繼承方案更好的解決方法映企,它極大減少了子類的個(gè)數(shù)悟狱。

  • 橋接模式提高了系統(tǒng)的可擴(kuò)展性,在兩個(gè)變化維度中任意擴(kuò)展一個(gè)維度堰氓,都不需要修改原有系統(tǒng)挤渐,符合“開閉原則”茁彭。

橋接模式缺點(diǎn):

  • 橋接模式的使用會(huì)增加系統(tǒng)的理解與設(shè)計(jì)難度混巧,由于關(guān)聯(lián)關(guān)系建立在抽象層面氓,要求開發(fā)者一開始就針對(duì)抽象層進(jìn)行設(shè)計(jì)與編程终畅。

  • 橋接模式要求正確識(shí)別出系統(tǒng)中兩個(gè)獨(dú)立變化的維度,因此其使用范圍具有一定的局限性鸽疾,如何正確識(shí)別兩個(gè)獨(dú)立維度也需要一定的經(jīng)驗(yàn)積累箱沦。

橋接模式適用場(chǎng)景:

  • 如果一個(gè)系統(tǒng)需要在抽象化和具體化之間增加更多的靈活性谈秫,避免在兩個(gè)層次之間建立靜態(tài)的繼承關(guān)系抚岗,通過橋接模式可以使它們?cè)诔橄髮咏⒁粋€(gè)關(guān)聯(lián)關(guān)系。

  • “抽象部分”和“實(shí)現(xiàn)部分”可以以繼承的方式獨(dú)立擴(kuò)展而互不影響哪怔,在程序運(yùn)行時(shí)可以動(dòng)態(tài)將一個(gè)抽象化子類的對(duì)象和一個(gè)實(shí)現(xiàn)化子類的對(duì)象進(jìn)行組合宣蔚,即系統(tǒng)需要對(duì)抽象化角色和實(shí)現(xiàn)化角色進(jìn)行動(dòng)態(tài)耦合。

  • 一個(gè)類存在兩個(gè)(或多個(gè))獨(dú)立變化的維度认境,且這兩個(gè)(或多個(gè))維度都需要獨(dú)立進(jìn)行擴(kuò)展胚委。

  • 對(duì)于那些不希望使用繼承或因?yàn)槎鄬永^承導(dǎo)致系統(tǒng)類的個(gè)數(shù)急劇增加的系統(tǒng),橋接模式尤為適用叉信。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末亩冬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子硼身,更是在濱河造成了極大的恐慌硅急,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佳遂,死亡現(xiàn)場(chǎng)離奇詭異营袜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)丑罪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門荚板,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凤壁,“玉大人,你說我怎么就攤上這事跪另∨《叮” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵免绿,是天一觀的道長(zhǎng)唧席。 經(jīng)常有香客問我,道長(zhǎng)针姿,這世上最難降的妖魔是什么袱吆? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮距淫,結(jié)果婚禮上绞绒,老公的妹妹穿的比我還像新娘。我一直安慰自己榕暇,他們只是感情好蓬衡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著彤枢,像睡著了一般狰晚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缴啡,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天壁晒,我揣著相機(jī)與錄音,去河邊找鬼业栅。 笑死秒咐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碘裕。 我是一名探鬼主播携取,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼帮孔!你這毒婦竟也來了雷滋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤文兢,失蹤者是張志新(化名)和其女友劉穎晤斩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姆坚,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡尸昧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旷偿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烹俗。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡爆侣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出幢妄,到底是詐尸還是另有隱情兔仰,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布蕉鸳,位于F島的核電站乎赴,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏潮尝。R本人自食惡果不足惜榕吼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勉失。 院中可真熱鬧羹蚣,春花似錦、人聲如沸乱凿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)徒蟆。三九已至胁出,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間段审,已是汗流浹背全蝶。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寺枉,地道東北人抑淫。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像型凳,于是被迫代替她去往敵國(guó)和親丈冬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嘱函,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348