Java學習記錄--適配器模式

Java學習記錄--適配器模式

標簽(空格分隔): java


適配器模式是一種比較簡單的設計模式,該博文從Java的Set集合入手,分析適配器模式適用場景,解決的問題,導致的缺點等.希望對你有幫助.


適配器模式,可以這樣解釋,用現(xiàn)有的組件去匹配實現(xiàn)要求提供的功能.舉個例子:對于Java的HashSet集合,實際上是由一個HashMap映射來實現(xiàn)的,那么就可以理解為用現(xiàn)有的HashMap組件去實現(xiàn)了要求沒有重復的Set集合這一功能.那么,這就是適配器模式,對于HashSet來說,更詳細的叫法是對象適配器模式.


1.對象適配器模式

舉個例子,MAC新款用的是雷電3接口,但是以前都是USB接口,那么就需要一個轉換器,提供USB到雷電3的數據傳輸轉換,那么在HashSet實現(xiàn)中每一個類都承擔什么角色呢?

首先看HashSet的部分源碼:

    //被適配的HashMap
    private transient HashMap<E,Object> map;
    //作為Map值的元素
    private static final Object PRESENT = new Object();
    //初始化被適配的HashMap
    public HashSet() {
        map = new HashMap<>();
    }

那么對于HashMap來說,HashMap就是USB接口,Set這個interface是新款的雷電3接口,于是HashSet就成了這個轉換器,所提供的功能是把HashMap中的key單獨表現(xiàn)為一個集合.

再看HashSet提供的轉換:

public int size() {
        return map.size();
    }
public boolean contains(Object o) {
        return map.containsKey(o);
    }
public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

就像插口適配器提供數據傳輸轉換一樣,HashSet提供對HashMap映射的轉換.這樣來看的話很容易理解.參考下圖:

1.jpg

2.類適配器

如果把HashSet改造成下面這種形式的話,那就是類適配器,顯然這種方式很不靈活,繼承導致方法的混亂沖突,調用的不清晰等.因此建議使用對象適配器.

public class HashSet<K> extends HashMap<K,Object> implements Set<K> {

    private static final Object PRESENT = new Object();

    @Override
    public boolean add(K k) {
        return super.put(k, PRESENT) == null;
    }

    @Override
    public boolean remove(Object key) {
        return super.remove(key) == PRESENT;
    }
}

3.總結

3.1適用情景

  1. 系統(tǒng)需要使用現(xiàn)有的類,而這些類的接口不符合系統(tǒng)的接口。
  2. 想要建立一個可以重用的類,用于與一些彼此之間沒有太大關聯(lián)的一些類,包括一些可能在將來引進的類一起工作。
  3. 兩個類所做的事情相同或相似,但是具有不同接口的時候。
  4. 舊的系統(tǒng)開發(fā)的類已經實現(xiàn)了一些功能,但是客戶端卻只能以另外接口的形式訪問,但我們不希望手動更改原有類的時候。
  5. 使用第三方組件,組件接口定義和自己定義的不同,不希望修改自己的接口,但是要使用第三方組件接口的功能。

3.2 優(yōu)點

  1. 通過適配器,客戶端可以調用同一接口,因而對客戶端來說是透明的。這樣做更簡單、更直接、更緊湊。
  2. 復用了現(xiàn)存的類,解決了現(xiàn)存類和復用環(huán)境要求不一致的問題。
  3. 將目標類和適配者類解耦,通過引入一個適配器類重用現(xiàn)有的適配者類,而無需修改原有代碼.
  4. 一個對象適配器可以把多個不同的適配者類適配到同一個目標,也就是說,同一個適配器可以把適配者類和它的子類都適配到目標接口。

3.3缺點

  1. 對象適配器造成代碼耦合,如果被適配的類,如HashMap由較為大的改動可能會影響適配器.另外更換適配器比較麻煩.
  2. 對于類適配器,不夠靈活,寫的不得當造成代碼混亂.

根據自己的業(yè)務選擇最適合的方式即可.

4.補充

4.1和裝飾者模式比較

適配器像是轉換器,使用新接口來調用原接口,并且有時候需要轉換下功能,不應該對外直接暴露被適配的類的功能,而是通過自己本身的方法提供.如下面方法:

public boolean contains(Object o) {
        return map.containsKey(o);
    }

裝飾者模式是提供新的職責,并且原封不動的提供被裝飾者功能.

適配器是知道被適配者的詳細情況的(就是那個類或那個接口)。裝飾者只知道其接口是什么,至于其具體類型(是基類還是其他派生類)只有在運行期間才知道。

兩者的有一個共同的名稱叫做'包裝模式',兩者的最主要的區(qū)別在于使用目的不同,其他則大致思想一致.

參考博文:
http://blog.csdn.net/jason0539/article/details/22468457

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容