適配器模式

1.適配器模式概念

作為兩個不兼容的接口之間的橋梁,它屬于結(jié)構(gòu)型模式。

2.適配器模式作用

適配器模式(Adapter Pattern),將一個類的接口轉(zhuǎn)換成客戶期望的另一個接口。適配器讓原本不兼容的類可以合作無間(《Head First Design Patterns》上解釋道)。

3.何時使用

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

4.優(yōu)點和缺點

優(yōu)點
1、可以讓任何兩個沒有關(guān)聯(lián)的類一起運行。
2、提高了類的復(fù)用。
3、增加了類的透明度。
4、靈活性好。
缺點
1、過多地使用適配器,會讓系統(tǒng)非常零亂,不易整體進行把握。比如,明明看到調(diào)用的是 A 接口,其實內(nèi)部被適配成了 B 接口的實現(xiàn),一個系統(tǒng)如果太多出現(xiàn)這種情況,無異于一場災(zāi)難。因此如果不是很有必要,可以不使用適配器,而是直接對系統(tǒng)進行重構(gòu)。
2.由于 JAVA 至多繼承一個類,所以至多只能適配一個適配者類,而且目標(biāo)類必須是抽象類。

5.適配器解析

適配器分為兩種,一種是對象適配器,一種是類適配器。對象適配器是使用組合實現(xiàn)的,而類適配器是使用繼承實現(xiàn)的,并且類適配器模式在JAVA中實現(xiàn)不了,因為它使用了多重繼承,需要使用支持多重繼承的語言才能實現(xiàn),如C++。
對象適配器類圖:

對象適配器類圖

類適配器類圖:

類適配器類圖

下面是類適配器源碼解析:這是通過適配器將火雞變成鴨子的例子
Target接口:即通過適配器將被適配者轉(zhuǎn)換成Target

public interface Duck {

    public void quack();
    public void fly();
}

Adapter:適配器

public class TrukeyAdapter implements Duck {

    Turkey turkey = null;
    public TrukeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }
    @Override
    public void fly() {
        for (int i = 0; i < 5; i++) {
            turkey.fly();
        }
    }

    @Override
    public void quack() {
        turkey.gobble();
    }
}

Adaptee:被適配者
被適配者接口:

public interface Turkey {

    public void gobble();
    public void fly();
}

被適配者具體實例:

public class WildTurkey implements Turkey {

    @Override
    public void fly() {
        System.out.println("I'm flying a short distance");
    }

    @Override
    public void gobble() {
        System.out.println("Gobble gobble");
    }
}

客戶端:

/**
 * @author Administrator
 *  Adapter---TrukeyAdapter
 *  Adaptee---Turkey
 *  Target---Duck
 *  
 */
public class DuckTestDrive {

    public static void main(String[] args) {
        MarllarDuck marllarDuck = new MarllarDuck();
        WildTurkey wildTurkey = new WildTurkey();
        Duck turkeyAdapter = new TrukeyAdapter(wildTurkey);
        System.out.println("The Turkey say......");
        wildTurkey.gobble();
        wildTurkey.fly();
        System.out.println("\nThe Duck say......");
        testDuck(marllarDuck);
        System.out.println("\nThe TrukeyAdapter say......");
        testDuck(turkeyAdapter);
    }
    
    
    private static void testDuck(Duck duck) {
        duck.quack();
        duck.fly();
    }
}

這個例子是《Head First Design Patterns》里面的,也許不太明白將火雞變成鴨子這個例子,那么來說一個比較容易理解的例子,中國電器的插頭和美國電器插頭不一樣,所以中國電器是無法插入美國的插排的,所以需要一個適配器,能讓中國電器的插頭能插上美國的插排。這里中國電器的插頭就像是火雞(被適配者),而美國的插頭就是鴨子(Target),我們要通過適配器將中國插頭變成美國插頭,這樣中國電器才能在美國使用。

6.總結(jié)

Client使用Adapter的過程:
1.Client通過Target接口調(diào)用Adapter的方法,對適配器發(fā)出請求。

//Duck就是Target
    private static void testDuck(Duck duck) {
        duck.quack();
        duck.fly();
    }

2.Adapter使用Adaptee接口把請求轉(zhuǎn)換成Adaptee的一個或多個調(diào)用接口。

//在適配器TrukeyAdapter中的quack()方法中,調(diào)調(diào)用了Adaptee(也就是Turkey的gobble()方法)
    @Override
    public void quack() {
        turkey.gobble();
    }

3.Client接收到調(diào)用結(jié)果,但并未察覺這一切是Adapter在啟轉(zhuǎn)換作用。

7.源碼地址

http://download.csdn.net/detail/lgywsdy/9749997

8.參考文章

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

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

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

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