模式設(shè)計(jì)之 適配器模式

前言:

適配器模式(Adapter Pattern)是作為兩個(gè)不兼容的接口之間的橋梁。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它結(jié)合了兩個(gè)獨(dú)立接口的功能。

適配器模式通過定義一個(gè)新的接口(對(duì)要實(shí)現(xiàn)的功能加以抽象),和一個(gè)實(shí)現(xiàn)該接口的Adapter(適配器)類來透明地調(diào)用外部組件。這樣替換外部組件時(shí),最多只要修改幾個(gè)Adapter類就可以了,其他源代碼都不會(huì)受到影響。

以手機(jī)為例子,每一種機(jī)型都自帶有充電器,有一天自帶充電器壞了,而且市場(chǎng)沒有這類型充電器可買了,怎么辦?萬能充電器就可以解決,這個(gè)萬能充電器就是適配器。

適配器模式有兩種形式,一種是類的適配,另一種自然就是對(duì)象的適配。

介紹:

1、意圖:將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。

2、主要解決主要解決在軟件系統(tǒng)中,常常要將一些"現(xiàn)存的對(duì)象"放到新的環(huán)境中,而新環(huán)境要求的接口是現(xiàn)對(duì)象不能滿足的。

3、何時(shí)使用:①系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要。 ②想要建立一個(gè)可以重復(fù)使用的類,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類,包括一些可能在將來引進(jìn)的類一起工作,這些源類不一定有一致的接口。 ③通過接口轉(zhuǎn)換,將一個(gè)類插入另一個(gè)類系中。(比如老虎和飛禽,現(xiàn)在多了一個(gè)飛虎,在不增加實(shí)體的需求下,增加一個(gè)適配器,在里面包容一個(gè)虎對(duì)象,實(shí)現(xiàn)飛的接口。)

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

5、關(guān)鍵代碼:適配器繼承或依賴已有的對(duì)象,實(shí)現(xiàn)想要的目標(biāo)接口。

6、優(yōu)點(diǎn): 1、可以讓任何兩個(gè)沒有關(guān)聯(lián)的類一起運(yùn)行。 2、提高了類的復(fù)用。 3、增加了類的透明度。 4、靈活性好。

7、缺點(diǎn): 1、過多地使用適配器,會(huì)讓系統(tǒng)非常零亂,不易整體進(jìn)行把握。比如,明明看到調(diào)用的是 A 接口,其實(shí)內(nèi)部被適配成了 B 接口的實(shí)現(xiàn),一個(gè)系統(tǒng)如果太多出現(xiàn)這種情況,無異于一場(chǎng)災(zāi)難。因此如果不是很有必要,可以不使用適配器,而是直接對(duì)系統(tǒng)進(jìn)行重構(gòu)。 2.由于 JAVA 至多繼承一個(gè)類,所以至多只能適配一個(gè)適配者類,而且目標(biāo)類必須是抽象類。

類的適配:

這種適配器由三種角色組成:

1、目標(biāo)(Target)角色:這就是所期待得到的接口。注意:由于這里討論的是類適配器模式,因此目標(biāo)不可以是類。

2、源(Adapee)角色:現(xiàn)在需要適配的接口。

3、適配器(Adaper)角色:適配器類是本模式的核心。適配器把源接口轉(zhuǎn)換成目標(biāo)接口。顯然,這一角色不可以是接口,而必須是具體類。

對(duì)象的適配:

對(duì)象的適配依賴于對(duì)象的組合,而不是類適配中的繼承。

示例:

1、類適配器

image

故事情景:手機(jī)充電用手機(jī)充電器充電,耳機(jī)用耳機(jī)充電器充電,現(xiàn)在要實(shí)現(xiàn)給手機(jī)充電的同時(shí)也能給耳機(jī)充電。

首先來一個(gè)IPhone的充電器類(Adaptee角色):

/**
 * 充電器接口
 */
public interface ICharge {
    void charge();
}


/**
 * 蘋果手機(jī)充電器需要適配的角色(Adapee)
 */
public class AppleCharger implements ICharge{
    public void charge(){
          System.out.println("The ApplePhone is charging ...");
    }
}

現(xiàn)在,要對(duì)這個(gè)特殊的充電器進(jìn)行適配,上個(gè)適配的接口(Target目標(biāo)角色):

/**
* 要對(duì)這個(gè)特殊的充電器進(jìn)行適配,適配器接口(Target角色)
*/
public interface IChargeAdapter {
     void charge();
}

創(chuàng)建類的適配器:

/**
 * 多接頭充電器,支持一邊充手機(jī),一邊充耳機(jī)(Adaper)
 */
public class MultipleJointsCharger extends AppleCharger implements IChargeAdapter{
    @Override
    public void charge() {
        super.charge();
        System.out.println("The Headset is charging ...");
    }
}

啟動(dòng)類:

/**
 * 啟動(dòng)類
 */
@SpringBootApplication
public class StartClass {
    public static void main(String[] args){
        MultipleJointsCharger multipleJointsCharger = new MultipleJointsCharger();
        multipleJointsCharger.charge();
    }
}

控制臺(tái):

image

 2、對(duì)象適配器

image

故事情景:蘋果手機(jī)用蘋果充電器充電,安卓手機(jī)用安卓手機(jī)充電,現(xiàn)在需要一個(gè)萬能充電器能給這兩種手機(jī)充電。

創(chuàng)建兩個(gè)充電器類(Adaptee源角色):

/**
 * 充電器接口
 */
public interface ICharge {
    void charge();
}

/**
 * 安卓手機(jī)充電器需要適配的角色(Adaptee)
 */
public class AndroidCharger implements ICharge{
    @Override
    public void charge() {
        System.out.println("The AndroidPhone is charging ...");
    }
}

/**
 * 蘋果手機(jī)充電器需要適配的角色(Adaptee)
 */
public class AppleCharger implements ICharge{
    public void charge(){
          System.out.println("The ApplePhone is charging ...");
    }
}

現(xiàn)在,要對(duì)這個(gè)特殊的充電器進(jìn)行適配,上個(gè)適配的接口(Target目標(biāo)角色):

/**
* 要對(duì)這個(gè)特殊的充電器進(jìn)行適配,適配器接口(Target角色)
*/
public interface IChargeAdapter {
     void charge();
}

創(chuàng)建類的適配器:

/**
 * 萬能充電器,類的適配器(Adaper)
 */
public class UniversalCharger implements IChargeAdapter{
    private ICharge charge;

    public UniversalCharger(ICharge charge){
        this.charge = charge;
    }

    @Override
    public void charge() {
        charge.charge();
    }
}

啟動(dòng)類:

/**
 * 啟動(dòng)類
 */
@SpringBootApplication
public class StartClass {
    public static void main(String[] args){
        UniversalCharger universalCharger = new UniversalCharger(new AppleCharger())
        universalCharger.charge();

        UniversalCharger universalCharger1 = new UniversalCharger(new AndroidCharger());
        universalCharger1.charge();
    }
}

控制臺(tái):

image

總結(jié):
(1)類的適配器模式:當(dāng)希望將一個(gè)類轉(zhuǎn)換成滿足另一個(gè)新接口的類時(shí),可以使用類的適配器模式,創(chuàng)建一個(gè)新類,繼承原有的類,實(shí)現(xiàn)新的接口即可。
(2)對(duì)象的適配器模式:當(dāng)希望將一個(gè)對(duì)象轉(zhuǎn)換成滿足另一個(gè)新接口的對(duì)象時(shí),可以創(chuàng)建一個(gè)包裝類,持有原類的一個(gè)實(shí)例,在包裝類的方法中,調(diào)用實(shí)例的方法就行。

最后編輯于
?著作權(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)容

  • 我的筆記本電腦的工作電壓是20V,而我國的家庭用電是220V,如何讓20V的筆記本電腦能夠在220V的電壓下工作?...
    justCode_閱讀 1,503評(píng)論 0 5
  • 我的筆記本電腦的工作電壓是20V,而我國的家庭用電是220V,如何讓20V的筆記本電腦能夠在220V的電壓下工作?...
    justCode_閱讀 870評(píng)論 0 1
  • 目錄 本文的結(jié)構(gòu)如下: 什么是適配器模式 為什么要用該模式 模式的結(jié)構(gòu) 代碼示例 優(yōu)點(diǎn)和缺點(diǎn) 適用環(huán)境 模式應(yīng)用 ...
    w1992wishes閱讀 989評(píng)論 0 3
  • 前言:設(shè)計(jì)模式之結(jié)構(gòu)型模式軟件模式與具體的應(yīng)用領(lǐng)域無關(guān),也就是說無論你從事的是移動(dòng)應(yīng)用開發(fā)、桌面應(yīng)用開發(fā)、Web ...
    markfork閱讀 2,567評(píng)論 4 13
  • 彭臻華 文 周末看了一部最近在國內(nèi)熱播的印度電影《起跑線》,講述的就是一對(duì)中產(chǎn)階級(jí)的印度夫婦拉吉和米圖,為了讓女兒...
    彭臻華閱讀 840評(píng)論 2 2

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