1. 程式人生 > >優雅的實現接口轉換——適配器模式詳解.md

優雅的實現接口轉換——適配器模式詳解.md

adaptee 測試 oid 相對 設計 情況下 之間 testcase over

1.前言

插頭轉換器我們應該都用過。當我們要使用二插頭的電器而身邊只有3孔的插座時,一個插頭轉換器就能解決插頭和插座不匹配的問題。如下圖所示
技術分享圖片

插頭轉換器其實只做了一件事,就是把原本不能使用的三孔插座轉換成了能使用的二孔插座。而這也正是我們接下來要講的適配器模式的本質:把不能被客戶端使用的接口轉換成了能被客戶端使用的接口。

2.適配器模式詳解

2.1適配器模式的定義

將一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。

2.2適配器模式的類結構

技術分享圖片

2.3適配器模式的實現

  • 客戶端代碼
public class Client {

    public void invokeTarget(Target target){
        target.request();
    }
}

客戶端中有個invokeTarget方法,方法接收一個Target接口作參數,我們來看看Target接口定義

  • 目標接口
public interface Target {

    void request();
}

我現在想讓目標類Adaptee的實例能被客戶端使用,能成功嗎?先來看看Adaptee的類定義

  • 目標類
public class Adaptee {

    public void request() {
        System.out.println("Adaptee!");
    }
}

因為Adaptee沒有實現Target接口,所以是沒辦法將它的實例作為參數供客戶端方法使用的,那麽有什麽好辦法嗎?接下來就是適配器出場的時候了

  • 適配器
public class Adapter implements Target {

    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.request();
    }
}

適配器類實現了Target接口,因而其可以被客戶端使用,又由於其內部持有目標類的實例,故而適配器類的工作都被委托給了目標類完成。

  • 測試
public class TestCase {

    public static void main(String[] args) {
        Client client = new Client();
        client.invokeTarget(new Adapter(new Adaptee()));
    }
}
  • 結果
    技術分享圖片

2.4適配器模式的使用場景

  • 需要使用的類庫不符合現有系統接口的要求
  • 不修改原有系統的情況下作舊系統的升級和改造

2.5類適配器

上面這種適配器其實叫對象適配器,還有種適配器的變體叫類適配器,關於這兩者的區別,也很簡單,看適配器類和目標類之間的關系是組合還是繼承,組合就是對象適配器,繼承就是類適配器。由於組合優於繼承,對象適配器相對來說要更常用些。

3總結

適配器實現了接口轉換,在不修改客戶端或者目標類的前提下,使得目標類與客戶端的接口兼容,從而可以一起工作,是常用且實用的設計模式。

優雅的實現接口轉換——適配器模式詳解.md