06 適配器模式(Adapter Design Pattern)

一句話概括:有點數(shù)據(jù)類型轉(zhuǎn)化輔助類的意思。

適配器模式將某個類的接口轉(zhuǎn)換成客戶端期望的另一個接口表示懂缕,主的目的是兼容性敷燎,讓原本因接口不匹配不能一起工作的兩個類可以協(xié)同工作。其別名為包裝器(Wrapper)拂共。

需要被適配的類、接口姻几、對象(我們有的)宜狐,簡稱 src(source)

最終需要的輸出(我們想要的),簡稱 dst (destination蛇捌,即Target)

適配器稱之為 Adapter 抚恒。

一句話描述適配器模式的感覺: src->Adapter->dst, 即src以某種形式(三種形式分別對應三種適配器模式)給到Adapter里,最終轉(zhuǎn)化成了dst络拌。

適配器設(shè)計模式的一個非常實際的例子是電源適配器俭驮。 手機電池充電電壓是3伏,但正常插座可以產(chǎn)生120V(美國)春贸、240V(印度)混萝、220V(中國)等。 因此萍恕,電源適配器可作為移動充電器和墻上插座之間的適配器逸嘀。

接下來我們嘗試使用適配器模式實現(xiàn)多適配器。

//電壓
public class Volt {

    private int volts;

    public Volt(int v){
        this.volts=v;
    }

    public int getVolts() {
        return volts;
    }

    public void setVolts(int volts) {
        this.volts = volts;
    }

}
//墻上的插座雄坪,輸出120V電壓
public class Socket {

    public Volt getVolt(){
        return new Volt(120);
    }
}

現(xiàn)在我們要構(gòu)建一個可產(chǎn)生3伏厘熟,12伏和默認120伏的適配器屯蹦。所以首先我們創(chuàng)建一個適配器接口维哈。

public interface SocketAdapter {

    public Volt get120Volt();

    public Volt get12Volt();

    public Volt get3Volt();
}

Two Way Adapter Pattern

在實現(xiàn)適配器模式時,有兩種方法 - 類適配器和對象適配器 - 但是這兩種方法都會產(chǎn)生相同的結(jié)果登澜。

  • 類適配器(Class Adapter) - 這種形式使用JAVA繼承(java inheritance)并擴展了原始接口阔挠,在我們的例子中是Socket類。
  • 對象適配器(Object Adapter) - 此種形式使用JAVA組合(Java Composition)并且適配器包含原始對象脑蠕。

Adapter Design Pattern – Class Adapter

//Using inheritance for adapter pattern
public class SocketClassAdapterImpl extends Socket implements SocketAdapter{

    @Override
    public Volt get120Volt() {
        return getVolt();
    }

    @Override
    public Volt get12Volt() {
        Volt v= getVolt();
        return convertVolt(v,10);
    }

    @Override
    public Volt get3Volt() {
        Volt v= getVolt();
        return convertVolt(v,40);
    }

    private Volt convertVolt(Volt v, int i) {
        return new Volt(v.getVolts()/i);
    }

}

Adapter Design Pattern – Object Adapter Implementation

public class SocketObjectAdapterImpl implements SocketAdapter{

    //Using Composition for adapter pattern
    private Socket sock = new Socket();

    @Override
    public Volt get120Volt() {
        return sock.getVolt();
    }

    @Override
    public Volt get12Volt() {
        Volt v= sock.getVolt();
        return convertVolt(v,10);
    }

    @Override
    public Volt get3Volt() {
        Volt v= sock.getVolt();
        return convertVolt(v,40);
    }

    private Volt convertVolt(Volt v, int i) {
        return new Volt(v.getVolts()/i);
    }
}

注意兩種適配器的實現(xiàn)幾乎相同购撼,他們都繼承了SocketAdapter接口跪削。適配器接口也可以是個抽象類。

下面是測試代碼:

public class AdapterPatternTest {

    public static void main(String[] args) {

        testClassAdapter();
        testObjectAdapter();
    }

    private static void testObjectAdapter() {
        SocketAdapter sockAdapter = new SocketObjectAdapterImpl();
        Volt v3 = getVolt(sockAdapter,3);
        Volt v12 = getVolt(sockAdapter,12);
        Volt v120 = getVolt(sockAdapter,120);
        System.out.println("v3 volts using Object Adapter="+v3.getVolts());
        System.out.println("v12 volts using Object Adapter="+v12.getVolts());
        System.out.println("v120 volts using Object Adapter="+v120.getVolts());
    }

    private static void testClassAdapter() {
        SocketAdapter sockAdapter = new SocketClassAdapterImpl();
        Volt v3 = getVolt(sockAdapter,3);
        Volt v12 = getVolt(sockAdapter,12);
        Volt v120 = getVolt(sockAdapter,120);
        System.out.println("v3 volts using Class Adapter="+v3.getVolts());
        System.out.println("v12 volts using Class Adapter="+v12.getVolts());
        System.out.println("v120 volts using Class Adapter="+v120.getVolts());
    }

    private static Volt getVolt(SocketAdapter sockAdapter, int i) {
        switch (i){
        case 3: return sockAdapter.get3Volt();
        case 12: return sockAdapter.get12Volt();
        case 120: return sockAdapter.get120Volt();
        default: return sockAdapter.get120Volt();
        }
    }
}

測試代碼的輸出結(jié)果是:

v3 volts using Class Adapter=3
v12 volts using Class Adapter=12
v120 volts using Class Adapter=120
v3 volts using Object Adapter=3
v12 volts using Object Adapter=12
v120 volts using Object Adapter=120

Adapter Design Pattern Example in JDK

在JDK中可以很容易找出幾個簡單的適配器模式的應用

java.util.Arrays#asList()
java.io.InputStreamReader(InputStream) (returns a Reader)
java.io.OutputStreamWriter(OutputStream) (returns a Writer)

使用場景

  • 系統(tǒng)需要使用現(xiàn)有的類迂求,而這些類的接口不符合系統(tǒng)的需要碾盐。
  • 想要建立一個可以重復使用的類,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類揩局,包括一些可能在將來引進的類一起工作毫玖。
  • 需要一個統(tǒng)一的輸出接口,而輸入端的類型不可預知凌盯。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末付枫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子驰怎,更是在濱河造成了極大的恐慌阐滩,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件县忌,死亡現(xiàn)場離奇詭異掂榔,居然都是意外死亡,警方通過查閱死者的電腦和手機症杏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門衅疙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鸳慈,你說我怎么就攤上這事饱溢。” “怎么了走芋?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵绩郎,是天一觀的道長。 經(jīng)常有香客問我翁逞,道長肋杖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任挖函,我火速辦了婚禮状植,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怨喘。我一直安慰自己津畸,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布必怜。 她就那樣靜靜地躺著肉拓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪梳庆。 梳的紋絲不亂的頭發(fā)上暖途,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天卑惜,我揣著相機與錄音,去河邊找鬼驻售。 笑死露久,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的欺栗。 我是一名探鬼主播抱环,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纸巷!你這毒婦竟也來了镇草?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瘤旨,失蹤者是張志新(化名)和其女友劉穎梯啤,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體存哲,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡因宇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了祟偷。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片察滑。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖修肠,靈堂內(nèi)的尸體忽然破棺而出贺辰,到底是詐尸還是另有隱情,我是刑警寧澤嵌施,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布饲化,位于F島的核電站,受9級特大地震影響吗伤,放射性物質(zhì)發(fā)生泄漏吃靠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一足淆、第九天 我趴在偏房一處隱蔽的房頂上張望巢块。 院中可真熱鬧,春花似錦巧号、人聲如沸族奢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歹鱼。三九已至,卻和暖如春卜高,著一層夾襖步出監(jiān)牢的瞬間弥姻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工掺涛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留庭敦,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓薪缆,卻偏偏與公主長得像秧廉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拣帽,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容