從零開始學(xué)設(shè)計(jì)模式(七)——橋接模式

橋接模式(Bridage Pattern)

此模式難度等級為中級猾编,屬結(jié)構(gòu)型模式限府,提出者為Gang Of Four

橋接(Bridge)是用于把抽象化與實(shí)現(xiàn)化解耦懂拾,使得二者可以獨(dú)立變化碳锈。

它通過提供抽象化和實(shí)現(xiàn)化之間的橋接結(jié)構(gòu)书在,來實(shí)現(xiàn)二者的解耦。

意圖

將抽象部分與實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立的變化

主要解決:在有多種可能會(huì)變化的情況下,用繼承會(huì)造成類爆炸問題笋庄,擴(kuò)展起來不靈活效扫。

何時(shí)使用:實(shí)現(xiàn)系統(tǒng)可能有多個(gè)角度分類,每一種角度都可能變化直砂。

如何解決:把這種多角度分類分離出來菌仁,讓它們獨(dú)立變化,減少它們之間耦合静暂。

關(guān)鍵代碼:抽象類依賴實(shí)現(xiàn)類济丘。

解釋

現(xiàn)實(shí)世界中的例子

考慮到你有一件武器具有不同的魔法,假如允許你讓不同的武器與不同的魔法混合洽蛀。你會(huì)怎么做摹迷?一為每個(gè)不同的魔法功能創(chuàng)建多個(gè)武器副本,二你會(huì)根據(jù)需要為武器創(chuàng)建單獨(dú)的魔法并設(shè)置它郊供。橋接模式就是你的第二選擇

簡而言之

橋接模式是關(guān)于更喜歡組合而不是繼承峡碉。實(shí)現(xiàn)細(xì)節(jié)從一個(gè)層次結(jié)構(gòu)派生到另一個(gè)具有單獨(dú)層次結(jié)構(gòu)的對象

維基百科

橋接模式是軟件工程中使用的一種設(shè)計(jì)模式,旨在“將抽象與其實(shí)現(xiàn)分離驮审,以便兩者可以獨(dú)立變化”

程序示例

以上面翻譯中我們現(xiàn)實(shí)世界中的武器例子鲫寄。如下來建造武器Weapon和魔法Enchantment的組合結(jié)構(gòu)。

image.png

首先編寫武器組織結(jié)構(gòu)代碼:

public interface Weapon {
  void wield();
  void swing();
  void unwield();
  Enchantment getEnchantment();
}

public class Sword implements Weapon {

  private final Enchantment enchantment;

  public Sword(Enchantment enchantment) {
    this.enchantment = enchantment;
  }

  @Override
  public void wield() {
    LOGGER.info("The sword is wielded.");
    enchantment.onActivate();
  }

  @Override
  public void swing() {
    LOGGER.info("The sword is swinged.");
    enchantment.apply();
  }

  @Override
  public void unwield() {
    LOGGER.info("The sword is unwielded.");
    enchantment.onDeactivate();
  }

  @Override
  public Enchantment getEnchantment() {
    return enchantment;
  }
}

public class Hammer implements Weapon {

  private final Enchantment enchantment;

  public Hammer(Enchantment enchantment) {
    this.enchantment = enchantment;
  }

  @Override
  public void wield() {
    LOGGER.info("The hammer is wielded.");
    enchantment.onActivate();
  }

  @Override
  public void swing() {
    LOGGER.info("The hammer is swinged.");
    enchantment.apply();
  }

  @Override
  public void unwield() {
    LOGGER.info("The hammer is unwielded.");
    enchantment.onDeactivate();
  }

  @Override
  public Enchantment getEnchantment() {
    return enchantment;
  }
}

其次編寫分離的魔法組織結(jié)構(gòu)代碼:

public interface Enchantment {
  void onActivate();
  void apply();
  void onDeactivate();
}

public class FlyingEnchantment implements Enchantment {

  @Override
  public void onActivate() {
    LOGGER.info("The item begins to glow faintly.");
  }

  @Override
  public void apply() {
    LOGGER.info("The item flies and strikes the enemies finally returning to owner's hand.");
  }

  @Override
  public void onDeactivate() {
    LOGGER.info("The item's glow fades.");
  }
}

public class SoulEatingEnchantment implements Enchantment {

  @Override
  public void onActivate() {
    LOGGER.info("The item spreads bloodlust.");
  }

  @Override
  public void apply() {
    LOGGER.info("The item eats the soul of enemies.");
  }

  @Override
  public void onDeactivate() {
    LOGGER.info("Bloodlust slowly disappears.");
  }
}

最后上面兩個(gè)組織層次都起作用疯淫,自動(dòng)橋接:

Sword enchantedSword = new Sword(new SoulEatingEnchantment());
enchantedSword.wield();
enchantedSword.swing();
enchantedSword.unwield();
// The sword is wielded.
// The item spreads bloodlust.
// The sword is swinged.
// The item eats the soul of enemies.
// The sword is unwielded.
// Bloodlust slowly disappears.

Hammer hammer = new Hammer(new FlyingEnchantment());
hammer.wield();
hammer.swing();
hammer.unwield();
// The hammer is wielded.
// The item begins to glow faintly.
// The hammer is swinged.
// The item flies and strikes the enemies finally returning to owner's hand.
// The hammer is unwielded.
// The item's glow fades.

應(yīng)用場景

當(dāng)遇到如下情況時(shí)你應(yīng)該使用橋接模式:

  • 你希望避免抽象與其實(shí)現(xiàn)之間的永久綁定地来。例如,在運(yùn)行時(shí)必須選擇或切換實(shí)現(xiàn)時(shí)熙掺,可能會(huì)出現(xiàn)這種情況

  • 抽象和它們的實(shí)現(xiàn)都應(yīng)該通過子類化來擴(kuò)展未斑。在這種情況下,Bridge模式允許你組合不同的抽象和實(shí)現(xiàn)币绩,并獨(dú)立地?cái)U(kuò)展它們

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

  • 抽象中的具體實(shí)現(xiàn)發(fā)生變化時(shí)不應(yīng)影響客戶端类浪;也就是說,客戶端他們的代碼不應(yīng)該被重新編譯

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

  • 你想在多個(gè)對象之間共享一個(gè)實(shí)現(xiàn)(也許使用引用計(jì)數(shù))费就,這個(gè)事實(shí)應(yīng)該對客戶端隱藏。一個(gè)簡單的例子是Coplien的String類川队,其中多個(gè)對象可以共享相同的String表示

寫在最后

對于一個(gè)類存在兩個(gè)獨(dú)立變化的維度力细,使用橋接模式是再適合不過了。

將抽象和實(shí)現(xiàn)放在兩個(gè)不同的類層次中固额,使它們可以獨(dú)立地變化眠蚂。——《Head First 設(shè)計(jì)模式》

將類的功能層次結(jié)構(gòu)和實(shí)現(xiàn)層次結(jié)構(gòu)相分離斗躏,使二者能夠獨(dú)立地變化逝慧,并在兩者之間搭建橋梁,實(shí)現(xiàn)橋接〉殉迹—— 《圖解設(shè)計(jì)模式》

類的功能層次結(jié)構(gòu):父類具有基本功能云稚,在子類中增加新的功能;

類的實(shí)現(xiàn)層次結(jié)構(gòu):父類通過聲明抽象方法來定義接口沈堡,子類通過實(shí)現(xiàn)具體方法來實(shí)現(xiàn)接口静陈;

橋接模式中有四個(gè)角色:

抽象化角色:使用實(shí)現(xiàn)者角色提供的接口來定義基本功能接口。

持有實(shí)現(xiàn)者角色诞丽,并在功能接口中委托給它鲸拥,起到搭建橋梁的作用;

注意僧免,抽象化角色并不是指它就是一個(gè)抽象類刑赶,而是指抽象了實(shí)現(xiàn)。

改善后的抽象化角色:作為抽象化角色的子類猬膨,增加新的功能角撞,也就是增加新的接口(方法);與其構(gòu)成類的功能層次結(jié)構(gòu)勃痴;

實(shí)現(xiàn)者角色:提供了用于抽象化角色的接口谒所;它是一個(gè)抽象類或者接口。

具體的實(shí)現(xiàn)者角色:作為實(shí)現(xiàn)者角色的子類沛申,通過實(shí)現(xiàn)具體方法來實(shí)現(xiàn)接口劣领;與其構(gòu)成類的實(shí)現(xiàn)層次結(jié)構(gòu)。

最后铁材,如果抽象和實(shí)現(xiàn)兩者做不到獨(dú)立地變化尖淘,就不算橋接模式。

下一篇文章我們將學(xué)習(xí)結(jié)構(gòu)性模式中的過濾器模式(Filter Pattern)

碼字不易著觉,各位看官如果喜歡的話村生,請給點(diǎn)個(gè)喜歡 ??,關(guān)注下我饼丘,我將努力持續(xù)不斷的為大家更新

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末趁桃,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子肄鸽,更是在濱河造成了極大的恐慌卫病,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件典徘,死亡現(xiàn)場離奇詭異蟀苛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)逮诲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門帜平,熙熙樓的掌柜王于貴愁眉苦臉地迎上來幽告,“玉大人,你說我怎么就攤上這事罕模∑老伲” “怎么了淑掌?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵蒿讥,是天一觀的道長。 經(jīng)常有香客問我抛腕,道長芋绸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任担敌,我火速辦了婚禮摔敛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘全封。我一直安慰自己马昙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布刹悴。 她就那樣靜靜地躺著行楞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪土匀。 梳的紋絲不亂的頭發(fā)上子房,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音就轧,去河邊找鬼证杭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛妒御,可吹牛的內(nèi)容都是我干的解愤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼乎莉,長吁一口氣:“原來是場噩夢啊……” “哼琢歇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起梦鉴,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎揭保,沒想到半個(gè)月后肥橙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秸侣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年存筏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宠互。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡椭坚,死狀恐怖予跌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情善茎,我是刑警寧澤券册,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站垂涯,受9級特大地震影響烁焙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耕赘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一骄蝇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧操骡,春花似錦九火、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至跨细,卻和暖如春鹦倚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背冀惭。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工震叙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人散休。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓媒楼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親戚丸。 傳聞我的和親對象是個(gè)殘疾皇子划址,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計(jì)原則時(shí)需要注意以下幾點(diǎn):a) 高內(nèi)聚、低耦合和單一職能的“沖突”實(shí)際上限府,這兩者...
    彥幀閱讀 3,734評論 0 14
  • 1 場景問題# 1.1 發(fā)送提示消息## 考慮這樣一個(gè)實(shí)際的業(yè)務(wù)功能:發(fā)送提示消息夺颤。基本上所有帶業(yè)務(wù)流程處理的系統(tǒng)...
    七寸知架構(gòu)閱讀 4,962評論 5 63
  • 設(shè)計(jì)模式匯總 一胁勺、基礎(chǔ)知識 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用世澜、多...
    MinoyJet閱讀 3,903評論 1 15
  • 1.初識橋接模式 將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化署穗。 Abstraction:抽象部分的接口寥裂。...
    王偵閱讀 903評論 0 7
  • 彼岸焦點(diǎn)分享第21天 昨天看到群里老師的分享嵌洼,說在陪伴孩子時(shí)遇到的困惑,不知該怎樣用焦點(diǎn)的方法去引領(lǐng)孩子封恰。...
    彼岸_8b4b閱讀 223評論 0 0