適配器模式 設計模式:適配器模式

定義

適配器模式:將一個類的接口轉換成客戶但願的另外一個接口。適配器模式讓那些接口不兼容的類能夠一塊兒工做html

主要解決:主要解決在軟件系統中,經常要將一些"現存的對象"放到新的環境中,而新環境要求的接口是現對象不能知足的。android

什麼時候使用:設計模式

  • 系統須要使用現有的類,而此類的接口不符合系統的須要。
  • 想要創建一個能夠重複使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在未來引進的類一塊兒工做,這些源類不必定有一致的接口。
  • 經過接口轉換,將一個類插入另外一個類系中。(好比老虎和飛禽,如今多了一個飛虎,在不增長實體的需求下,增長一個適配器,在裏面包容一個虎對象,實現飛的接口。)

如何解決:繼承或依賴(推薦)。app

關鍵代碼:適配器繼承或依賴已有的對象,實現想要的目標接口。ide

適配器模式的結構

適配器模式的別名爲包裝器(Wrapper)模式,它既能夠做爲類結構型模式,也能夠做爲對象結構型模式。在適配器模式定義中所說起的接口是指廣義的接口,它能夠表示一個方法或者方法的集合。函數

類適配器模式結構圖:

對象適配器結構圖:

    

由圖可知適配器模式包含一下三個角色:post

  1. Target (目標抽象類):目標抽象類定義客戶所需的接口,能夠是一個抽象類或接口,也能夠是具體類。在類適配器中,因爲C#語言不支持多重繼承,因此它只能是接口。this

  2. Adapter (適配器類):它能夠調用另外一個接口,做爲一個轉換器,對 Adaptee 和 Target 進行適配。它是適配器模式的核心。url

  3. Adaptee (適配者類):適配者即被適配的角色,它定義了一個已經存在的接口,這個接口須要適配,適配者類包好了客戶但願的業務方法。spa

代碼實戰

例如美國的電壓是 110v,中國的電壓是220。當咱們到美國的時候,使用國產自帶的電器的時候,就須要將電壓轉爲220,才能使用。

下面咱們將上面的例子轉爲代碼。

類適配器模式

/**
 * Traget角色
 */
public interface Volt110 {
    int getVolt110();
}

/**
 * adaptee角色,須要被轉換的對象
 */
public class Volt220 {
    public int getVolt220() {
        return 220;
    }
}

/**
 * Adapter 角色,將 220V 的電壓轉換爲 110V 的電壓
 */
public class VoltAdapter extends Volt220 implements Volt110 {
    @Override
    public int getVolt110() {
        return 110;
    }
}

Target 角色給出了須要的目標接口,而 Adaptee 類則是須要被轉換的對象。Adapter 則是將 Volt220 轉換成 Target 的接口。對應的 Target 的目標是要獲取 110V 的輸出電壓,而 Adaptee 正常輸出電壓是 220V,此時就須要電源適配器類將 220V 的電壓轉換爲 110V 電壓,解決接口不兼容的問題。

對於類適配器模式,adpter 須要繼承被轉化者對象,同時也要實現適配目標的接口,這樣才能將自身轉爲目標。

public class Test {
    public static void main() {
        VoltAdapter adapter = new VoltAdapter();
        Log.d("輸出電壓", "" + adapter.getVolt110());
    }
}

對象適配器模式

 與類適配器有點區別的是,這裏使用了代理模式來輸出220v的電壓。

/**
 * Traget角色
 */
public interface Volt110 {
    int getVolt110();
}

/**
 * adaptee角色,須要被轉換的對象
 */
public class Volt220 {
    public int getVolt220() {
        return 220;
    }
}

/**
 * Adapter 角色,將 220V 的電壓轉換爲 110V 的電壓
 */
public class VoltAdapter implements Volt110 {
    Volt220 mVolt220;

    public VoltAdapter(Volt220 adaptee){
        this.mVolt220 = adaptee;
    }

    public int getVolt220() {
        return mVolt220.getVolt220();
    }

    @Override
    public int () {
        return 110;
    }
}

使用方式以下:

public class Test {
    public static void main() {
        VoltAdapter adapter = new VoltAdapter(new Volt220());
        Log.d("輸出電壓", "" + adapter.getVolt110());
    }
}

這種實現方式直接將要適配的對象傳遞到 Adapter 中,使用組合的形式實現接口兼容的效果。這比類適配器方式更爲靈活,它的另外一個好處是被適配對象中的方法不會暴露出來,而類適配器因爲繼承了被適配器對象,所以,被適配對象類的函數在 Adapter 類中也都含有,這使得 Adapter 類出現一些奇怪的接口,用戶使用成本較高。所以,對象適配器模式更加靈活、使用。

適配器模式的優缺點

優勢:

  1. 將目標類和適配者類解耦,經過引入一個適配器類來重用現有的適配者類,無需修改原有結構。

  2. 增長了類的透明性和複用性,將具體的業務實現過程封裝在適配者類中,對於客戶端類而言是透明的,並且提升了適配者的複用性,同一適配者類能夠在多個不一樣的系統中複用。

  3. 靈活性和擴展性都很是好,經過使用配置文件,能夠很方便的更換適配器,也能夠在不修改原有代碼的基礎上 增長新的適配器,徹底複合開閉原則。

缺點:

  1. 一次最多隻能適配一個適配者類,不能同時適配多個適配者。

  2. 適配者類不能爲最終類,在C#中不能爲sealed類

  3. 目標抽象類只能爲接口,不能爲類,其使用有必定的侷限性。

應用實例

  1. 美國電器 110V,中國 220V,就要有一個適配器將 110V 轉化爲 220V。

  2. JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,則要將之前系統的 Enumeration 接口轉化爲 Iterator 接口,這時就須要適配器模式。

  3. 在 LINUX 上運行 WINDOWS 程序。

  4. JAVA 中的 jdbc。

  5. android 中的 listview adpter 等

 

參考文獻

一、設計模式:適配器模式

二、http://www.runoob.com/design-pattern/adapter-pattern.html

相關文章
相關標籤/搜索