23天學(xué)習(xí)23種設(shè)計(jì)模式——適配器模式

前言

買過(guò)港版手機(jī)的都知道,包裝盒里送的充電頭是港標(biāo)的。和我們大陸日常使用的國(guó)標(biāo)是不兼容的。也就是說(shuō),港版手機(jī)直接用送的充電頭是無(wú)法在大陸直接充電的。這是由于大陸使用國(guó)標(biāo)插座,而HK是使用的英標(biāo)插座。如下圖所示,可以看到國(guó)標(biāo),港版英標(biāo)的是不同接口的插座。

各國(guó)插座標(biāo)準(zhǔn)

而為了解決這個(gè)不兼容的問(wèn)題,通常使用電源接頭轉(zhuǎn)換器,這種轉(zhuǎn)換器一頭是英標(biāo)接口,另一頭是國(guó)標(biāo)插頭。有了轉(zhuǎn)換器,我們可以在不更換插座接口,也不更換充電器的前提下,成功將我們的港版手機(jī)充電。

電源接頭轉(zhuǎn)換器

在軟件開發(fā)中,我們也會(huì)遇到需要“電源接頭轉(zhuǎn)換器”的時(shí)候。比如說(shuō),需要使用現(xiàn)有的類,但是類的接口并不符合我們的需要,甚至是并沒有這些類的源代碼。此時(shí),適配器模式就是我們的轉(zhuǎn)化器。

是什么

適配器模式(Adapter Pattern):將一個(gè)接口轉(zhuǎn)換成客戶希望的另一個(gè)接口,使接口不兼容的那些類可以一起工作,其別名為包裝器(Wrapper)。適配器模式既可以作為類結(jié)構(gòu)型模式,也可以作為對(duì)象結(jié)構(gòu)型模式。常用作在不修改源代碼的情況下讓已經(jīng)存在的類能和其他類一起使用。

根據(jù)適配器類和適配者類的關(guān)系,適配器模式可以分為以下兩種:

  • 對(duì)象適配器模式(組合的方式)

  • 類適配器模式(繼承的方式)


    兩種適配器模式(左邊對(duì)象適配器模式,右邊類適配器模式)
  • Target:目標(biāo)抽象類,定義客戶所需的接口,可以是抽象類/接口/具體類。

  • Adaptee:適配者類,也就是被適配的對(duì)象。定義一個(gè)已經(jīng)存在的接口。一般是一個(gè)具體類,其中包含了客戶希望使用的業(yè)務(wù)方法。

  • Adapter:適配器類,轉(zhuǎn)換器,對(duì)目標(biāo)類和適配者類進(jìn)行適配。

為什么

試想一下,如果我們不使用適配器模式,我們可以選擇修改源碼或者更改我們的目標(biāo)接口。而修改源碼或是更改接口很大的代價(jià)很大,甚至是我們根本就沒有源碼。就好像我們無(wú)法更換插座接口或是充電器的接頭一樣。

怎么做

由于適配器模式有多種,下面通過(guò)幾個(gè)代碼片段來(lái)分別學(xué)習(xí)一下:

  • 對(duì)象適配器模式
    首先是我們要使用的目標(biāo)接口,這個(gè)就好比是國(guó)標(biāo)插座。
/**
 * 目標(biāo)接口
 */
public interface Target {

    void request();

}

然后是我們的適配者類,同樣這個(gè)好比是港版英標(biāo)插頭。

/**
 * 適配者類
 */
public class Adaptee {

    /**
     * 客戶期望使用的業(yè)務(wù)方法
     */
    public void specificRequest(){
        System.out.println("Adaptee Specific request!");
    }
    
}

下面是適配器類,使用的是對(duì)象適配器模式,適配器類以組合的方式引用適配者類。這個(gè)就相當(dāng)于電源接頭轉(zhuǎn)換器。

/**
 * 適配器類(對(duì)象適配器模式實(shí)現(xiàn))
 */
public class Adapter implements Target {

    //以組合的方式關(guān)聯(lián)適配者
    private Adaptee adaptee;

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

    public void setAdaptee(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    /**
     * 對(duì)接口進(jìn)行轉(zhuǎn)換
     */
    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

  • 類適配器模式

而類適配器模式則是通過(guò)繼承的方式,而Java語(yǔ)言只支持單繼承,所以用得不多。

/**
 * 類適配器模式
 */
public class Adapter extends Adaptee implements Target {
    @Override
    public void request() {
        specificRequest();
    }
}

實(shí)際使用:

public class Client {
    public static void main(String[]args){
        Adaptee adaptee = new Adaptee();
        Target target = new Adapter(adaptee);
        target.request();
    }
}

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容