適配器模式

適配器模式

說到適配器壳坪,小秋第一想到的是我們電腦的電源適配器舶得,它能夠?qū)?20v,110v等不同電壓轉(zhuǎn)換為我們電腦需要的電壓值供電腦使用,那么你知道適配器模式是怎樣實現(xiàn)的嗎爽蝴,下面就和小秋一起探索一下適配器的工作模式吧

定義

將一個類的接口轉(zhuǎn)換成客戶希望的另一個接口

動機

通常情況下沐批,客戶端可以通過目標(biāo)類的接口訪問它所提供的服務(wù)。有時蝎亚,現(xiàn)有的類可以滿足客戶類的功能需要九孩,但是它所提供的接口不一定是客戶類所期望的,這可能是因為現(xiàn)有類中方法名與目標(biāo)類中定義的方法名不一致等原因所導(dǎo)致的颖对。

組件

  • 目標(biāo)(Target)角色:客戶端所期待得到的接口捻撑,

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

  • 源(Adapee)角色被適配者:現(xiàn)在需要被適配的接口

分類

類適配器模式

定義

通過多重繼承將apdatee2接口與target接口進行匹配江解,將適配的類apdatee2的API轉(zhuǎn)換成為目標(biāo)類的API

結(jié)構(gòu)

leiAdapter.png

優(yōu)點

  • 適配器可以重定義Adaptee的部分行為,相當(dāng)于子類覆蓋父類的部分實現(xiàn)方法徙歼。

  • 僅僅引入了一個對象犁河,并不需要額外的引用來間接得到Adaptee

缺點

由于適配器直接繼承了Adaptee鳖枕,使得適配器不能和Adaptee的子類一起工作,因為繼承是靜態(tài)的關(guān)系桨螺,當(dāng)適配器繼承了Adaptee后宾符,就不可能再去處理 Adaptee的子類了

對象的適配器模式

定義

被適配的類的API轉(zhuǎn)換成為目標(biāo)類的API,與類的適配器模式不同的是灭翔,對象的適配器模式不是使用繼承關(guān)系連接到Adaptee類而是使用委派關(guān)系連接到Adaptee類

結(jié)構(gòu)

ObjectAdapter.png

優(yōu)點

  • 一個適配器可以把多種不同的源適配到同一個目標(biāo)魏烫。換言之,同一個適配器可以把源類和它的子類都適配到目標(biāo)接口肝箱。因為對象適配器采用的是對象組合的關(guān)系哄褒,只要對象類型正確,是不是子類都無所謂煌张。

  • 符合設(shè)計原則:多用合成/聚合呐赡、少用繼承,從而減少類之間的耦合

缺點

  • 要重定義Adaptee的行為比較困難骏融,這種情況下链嘀,需要定義Adaptee的子類來實現(xiàn)重定義,然后讓適配器組合子類绎谦。雖然重定義Adaptee的行為比較困難管闷,但是想要增加一些新的行為則方便的很,而且新增加的行為可同時適用于所有的源

  • 需要額外的引用來間接得到Adaptee窃肠。

目標(biāo)接口(客戶端調(diào)用的接口)

package adapter;

//目標(biāo)接口(客戶端需要使用的接口)
public interface Target {
    //客戶端需要請求處理的方法
    public void request();
}

源接口(需要被適配的接口)

package adapter;

//源接口(已經(jīng)存在的接口)
//需要被轉(zhuǎn)換的對象
//這個接口需要重新配置以適應(yīng)目標(biāo)接口
public class Adaptee {

    public void specifiRequest() {
        System.out.println("源接口對象調(diào)用源接口中的方法");
    }
}

適配器

package adapter;

public class Adapter implements Target {

    //持有源接口對象
    private Adaptee adaptee;

    /**
     * 構(gòu)造方法,傳入需要被適配的對象
     * @param adaptee
     */
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    /**
     * 重寫目標(biāo)接口的方法刷允,以適應(yīng)客戶端的需求
     */
    @Override
    public void request() {
        //調(diào)用源接口的方法
        System.out.println("適配器包裝源接口對象冤留,調(diào)用源接口的方法");
        adaptee.specifiRequest();
    }
}

客戶端

package adapter;

public class Client {
    public static void main(String[] args){

        //創(chuàng)建源對象(被適配的對象)
        Adaptee adaptee = new Adaptee();
        //利用源對象對象一個適配器對象,提供客戶端調(diào)用的方法
        Adapter adapter = new Adapter(adaptee);
        System.out.println("客戶端調(diào)用適配器中的方法");
        adapter.request();

    }
}
//客戶端調(diào)用適配器中的方法
//適配器包裝源接口對象树灶,調(diào)用源接口的方法
//源接口對象調(diào)用源接口中的方法

優(yōu)點

目標(biāo)類和適配者類解耦纤怒,增加了類的透明性和復(fù)用性,同時系統(tǒng)的靈活性和擴展性都非常好天通,更換適配器或者增加新的適配器都非常方便泊窘,符合“開閉原則”

缺點

過多的使用適配器,會讓系統(tǒng)非常零亂像寒,不易整體進行把握烘豹。比如,明明看到調(diào)用的是A接口诺祸,其實內(nèi)部被適配成了B接口的實現(xiàn)

應(yīng)用案例

Java語言的數(shù)據(jù)庫連接工具JDBC携悯,JDBC給出一個客戶端通用的抽象接口,每一個具體數(shù)據(jù)庫引擎(如SQL Server筷笨、Oracle憔鬼、MySQL等)的JDBC驅(qū)動軟件都是一個介于JDBC接口和數(shù)據(jù)庫引擎接口之間的適配器軟件

應(yīng)用場景

  • 后期維護龟劲,由于不同的廠家不同的產(chǎn)品以及不同的開發(fā)人員

  • 調(diào)用第三方組件

  • 雙方都不太容易修改的時候

用途

想要復(fù)用一些現(xiàn)有的類,但是接口與復(fù)用環(huán)境要求不一致

適配器模式與裝飾模式的對比

UML圖

  • 適配器模式


    compareAdapter.png
  • 裝飾器模式


    compareDerector.png

內(nèi)容

  • 適配器模式

    • 持有的是待適配的對象轴或,實現(xiàn)的是目標(biāo)接口昌跌,兩個不一樣

    • 擴展了待適配類新的功能

    • 適配器模式拓展了新的功能

  • 裝飾器模式

    • 持有對象和繼承的對象一般是同一個類或接口

    • 裝飾模式中裝飾過的類力求與原來對外接口一致,這使得在調(diào)用方看來照雁,裝飾過后的類與之前沒有什么區(qū)別蚕愤,只是某一方面功能增強了

    • 裝飾模式增強了原有功能

總結(jié)

'裝飾模式與適配器模式是不沖突的,可以既增強原有功能囊榜,又添加全新的功能审胸。

最后附上一張適配器的概覽圖


overviewadaper1.png

參考

適配器模式

《JAVA與模式》之適配器模式

【Java基礎(chǔ)】淺談常見設(shè)計模式

適配器模式原理及實例介紹

適配器模式、裝飾模式卸勺、代理模式的異同

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末砂沛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子曙求,更是在濱河造成了極大的恐慌碍庵,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悟狱,死亡現(xiàn)場離奇詭異静浴,居然都是意外死亡,警方通過查閱死者的電腦和手機挤渐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門苹享,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浴麻,你說我怎么就攤上這事得问。” “怎么了软免?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵宫纬,是天一觀的道長。 經(jīng)常有香客問我膏萧,道長漓骚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任榛泛,我火速辦了婚禮蝌蹂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘挟鸠。我一直安慰自己叉信,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布艘希。 她就那樣靜靜地躺著硼身,像睡著了一般硅急。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上佳遂,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天营袜,我揣著相機與錄音,去河邊找鬼丑罪。 笑死荚板,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吩屹。 我是一名探鬼主播跪另,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼煤搜!你這毒婦竟也來了免绿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤擦盾,失蹤者是張志新(化名)和其女友劉穎嘲驾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迹卢,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡辽故,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了腐碱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片誊垢。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖症见,靈堂內(nèi)的尸體忽然破棺而出彤枢,到底是詐尸還是另有隱情,我是刑警寧澤筒饰,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站壁晒,受9級特大地震影響瓷们,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秒咐,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一谬晕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧携取,春花似錦攒钳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽文兢。三九已至,卻和暖如春焕檬,著一層夾襖步出監(jiān)牢的瞬間姆坚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工实愚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留兼呵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓腊敲,卻偏偏與公主長得像击喂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子碰辅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

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