結構型模式----橋接模式

pszh發表於2016-08-02

1.由來

設想如果要繪製矩形、圓形、橢圓、正方形,我們至少需要4個形狀類,但是如果繪製的圖形需要具有不同的顏色,如紅色、綠色、藍色等,此時至少有如下兩種設計方案:

  • 第一種設計方案是為每一種形狀都提供一套各種顏色的版本。
  • 第二種設計方案是根據實際需要對形狀和顏色進行組合

對於有兩個變化維度(即兩個變化的原因)的系統,採用方案二來進行設計系統中類的個數更少,且系統擴充套件更為方便。設計方案二即是橋接模式的應用。(我喜歡叫他拼湊模式,先抽取共同點,然後用共同點去拼湊)

2.定義

橋接模式(Bridge Pattern):將抽象部分與它的實現部分分離,使它們都可以獨立地變化。它是一種物件結構型模式,又稱為柄體(Handle and Body)模式或介面(Interface)模式。

3.程式碼的實現

抽象車

public abstract class AbstractCar {

  protected Transmission gear;
  
  public abstract void run();
  
  public void setTransmission(Transmission gear) {
    this.gear = gear;
  }
  
}

按品牌分,BMW牌車

public class BMWCar extends AbstractCar{

  private static final Logger LOG = LoggerFactory.getLogger(BMWCar.class);
  
  @Override
  public void run() {
    gear.gear();
    LOG.info("BMW is running");
  };

}
BenZCar
public class BenZCar extends AbstractCar{

  private static final Logger LOG = LoggerFactory.getLogger(BenZCar.class);
  
  @Override
  public void run() {
    gear.gear();
    LOG.info("BenZCar is running");
  };

}

抽象變速器
public abstract class Transmission{

  public abstract void gear();

}
手動檔
public class Manual extends Transmission {

  private static final Logger LOG = LoggerFactory.getLogger(Manual.class);

  @Override
  public void gear() {
    LOG.info("Manual transmission");
  }
}

自動檔
public class Auto extends Transmission {

  private static final Logger LOG = LoggerFactory.getLogger(Auto.class);

  @Override
  public void gear() {
    LOG.info("Auto transmission");
  }

有了變速器和品牌兩個維度各自的實現後,可以通過聚合,實現不同品牌不同變速器的車,如下
public class BridgeClient {

  public static void main(String[] args) {
    Transmission auto = new Auto();
    AbstractCar bmw = new BMWCar();
    bmw.setTransmission(auto);
    bmw.run();
    

    Transmission manual = new Manual();
    AbstractCar benz = new BenZCar();
    benz.setTransmission(manual);
    benz.run();
  }

}



4.模式的優點

  • 分離抽象介面及其實現部分。
  • 橋接模式有時類似於多繼承方案,但是多繼承方案違背了類的單一職責原則(即一個類只有一個變化的原因),複用性比較差,而且多繼承結構中類的個數非常龐大,橋接模式是比多繼承方案更好的解決方法。
  • 橋接模式提高了系統的可擴充性,在兩個變化維度中任意擴充套件一個維度,都不需要修改原有系統。
  • 實現細節對客戶透明,可以對使用者隱藏實現細節。

5.模式的缺點

  • 橋接模式的引入會增加系統的理解與設計難度,由於聚合關聯關係建立在抽象層,要求開發者針對抽象進行設計與程式設計。 - 橋接模式要求正確識別出系統中兩個獨立變化的維度,因此其使用範圍具有一定的侷限性。

6.應用場景

  • 如果一個系統需要在構件的抽象化角色和具體化角色之間增加更多的靈活性,避免在兩個層次之間建立靜態的繼承聯絡,通過橋接模式可以使它們在抽象層建立一個關聯關係。
  • 抽象化角色和實現化角色可以以繼承的方式獨立擴充套件而互不影響,在程式執行時可以動態將一個抽象化子類的物件和一個實現化子類的物件進行組合,即系統需要對抽象化角色和實現化角色進行動態耦合。
  • 一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴充套件。
  • 雖然在系統中使用繼承是沒有問題的,但是由於抽象化角色和具體化角色需要獨立變化,設計要求需要獨立管理這兩者。
  • 對於那些不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加的系統,橋接模式尤為適用



相關文章