橋接模式


一、概述

一般問題:一個類需要在兩個以上維度擴展,采用繼承方式會導致子類數量過多

核心方案:將抽象部分與實現部分分離,使其都可以獨立變化

設計意圖:橋接模式不是將兩個不相干的類鏈接,而是將一個需要多維度變化的類拆分成抽象部分和實現部分,並且在抽象層對兩者做組合關聯,是用組合的方式來解決繼承的問題。舉個例子,如果一個類在兩個維度分別有m和n種變化,采用繼承的方式就需要擴展出m*n個子類,且一個維度每增加一種變化就多出另一個維度變化總數的子類;如果將兩個維度拆分再組合,加起來也只有m+n個子類,且每個維度獨立擴展,一個維度增加一種變化只需要增加1個子類。

如上圖,Abstraction就是橋接模式中的“橋”,它含有一個實現部分實例,且提供動態設置具體實現類地方法,這樣抽象部分和實現部分的子類可以隨意組合。

下面舉一個簡單的例子:夏天都喜歡吃燒烤,就以燒烤為例,我們從兩個維度分析:從食材上有雞翅、雞腿等;從風味上有微辣、特辣等。

我們把食材做為抽象部分,把風味作為實現部分:

 

先看實現部分變化:

風味類Spicy

 public interface Spicy{
       String taste();
 }

微辣SlightSpicy

public class SlightSpicy implements Spicy{
     public String taste(){
          return "微辣";
     }
}

特辣ExtraSpicy

public class ExtraSpicy implements Spicy{
     public String taste(){
          return "特辣";
     }
}

再看抽象部分變化:

燒烤類Barbecue

public abstract class Barbecue{
     protected Spicy mSpicy;    //實現部分實例
     public Barbecue(Spicy spicy){    橋接模式的關鍵,組合實現和抽象
          this.mSpicy= spicy;
     }
     public abstract void eat();
}

雞翅類ChickenWing

public class ChickenWing extends Barbecue{
    public ChickenWing (Spicy spicy){
         super(spicy);
    }
     public void eat(){
           System.out.println( "雞翅:"+super.mSpicy.taste());
     }
}

測試:

public class Test{
     public static void main(String[] args){
         Barbecue barbecue = new ChickenWing(new SlightSpicy());
         barbecue .eat();
         Barbecue barbecue2 = new ChickenWing(new ExtraSpicy());
         barbecue2 .eat();
     }
}

輸出:

雞翅:微辣
雞翅:特辣

二、實戰應用

 我們知道Android中ListView的Adapter的設計用到了適配器模式,實際上Adapter本身還包含在一個橋接模式之中!

上圖是整個AdapterView類圖,對比橋接模式的UML圖,不難看出整體上它是個大的橋接模式,我們抽取其中的AbsListView這個小的橋接模式來分析:

AbsListView表示集合視圖,其有兩個維度變化:

  1. 顯示形式變化,如列表形式ListView或網格形式GridView;
  2. 數據類型變化,如字符串數組SimpleAdapter或數據庫游標CursorAdapter

Android將顯示形式作為抽象部分,數據類型作為實現部分,兩個部分各自獨立變化。

抽象部分和實現部分在AbsListView抽象層做了組合關聯,體現代碼如下:

public abstract class AbsListView extends AdapterView<ListAdapter>{
  ListAdapter mAdapter;    
  @Override
    public void setAdapter(ListAdapter adapter) {
        if (adapter != null) {
            mAdapterHasStableIds = mAdapter.hasStableIds();
            if (mChoiceMode != CHOICE_MODE_NONE && mAdapterHasStableIds &&
                    mCheckedIdStates == null) {
                mCheckedIdStates = new LongSparseArray<Integer>();
            }
        }
        clearChoices();
    }
}

三、總結

總結:橋接模式是一種結構型設計模式,根據最小繼承原則,將各個變化部分分離,從而實現獨立變化互不干涉,但又在更高的抽象層實現組合以保證各子類能動態結合。

用一句話來概括橋接模式:

“打斷骨頭還連着筋”

優點:

  • 抽象和實現分離
  • 易於擴展

缺點:橋接模式的引入會增加系統的理解與設計難度,由於聚合關聯關系建立在抽象層,要求開發者針對抽象進行設計與編程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM