簡(jiǎn)說(shuō)設(shè)計(jì)模式之適配器模式

前言:對(duì)于設(shè)計(jì)模式基礎(chǔ)概念可以去看[簡(jiǎn)說(shuō)設(shè)計(jì)模式之設(shè)計(jì)模式概述]

一、什么是適配器模式

適配器模式(Adapter)的定義如下:將一個(gè)類(lèi)的接口轉(zhuǎn)換成客戶(hù)希望的另外一個(gè)接口,使得原本由于接口不兼容而不能一起工作的那些類(lèi)能一起工作。適配器模式分為類(lèi)結(jié)構(gòu)型模式和對(duì)象結(jié)構(gòu)型模式兩種

1. 類(lèi)適配器

1.1 UML結(jié)構(gòu)圖

類(lèi)適配.gif

1.2 模式實(shí)現(xiàn)代碼

package adapter;
//目標(biāo)接口
interface Target
{
    public void request();
}
//適配者接口
class Adaptee
{
    public void specificRequest()
    {       
        System.out.println("適配者中的業(yè)務(wù)代碼被調(diào)用!");
    }
}
//類(lèi)適配器類(lèi)
class ClassAdapter extends Adaptee implements Target
{
    public void request()
    {
        specificRequest();
    }
}
//客戶(hù)端代碼
public class ClassAdapterTest
{
    public static void main(String[] args)
    {
        System.out.println("類(lèi)適配器模式測(cè)試:");
        Target target = new ClassAdapter();
        target.request();
    }
}

2.對(duì)象適配器

2.1 UML結(jié)構(gòu)圖

對(duì)象適配.gif

2.2 模式實(shí)現(xiàn)代碼

package adapter;
//對(duì)象適配器類(lèi)
class ObjectAdapter implements Target
{
    private Adaptee adaptee;
    public ObjectAdapter(Adaptee adaptee)
    {
        this.adaptee=adaptee;
    }
    public void request()
    {
        adaptee.specificRequest();
    }
}
//客戶(hù)端代碼
public class ObjectAdapterTest
{
    public static void main(String[] args)
    {
        System.out.println("對(duì)象適配器模式測(cè)試:");
        Adaptee adaptee = new Adaptee();
        Target target = new ObjectAdapter(adaptee);
        target.request();
    }
}

二、適配器模式的應(yīng)用

1. 何時(shí)使用

  • 系統(tǒng)需要使用現(xiàn)有的類(lèi),而此類(lèi)的接口不符合系統(tǒng)的需要。
  • 想建立一個(gè)可以重復(fù)使用的類(lèi),用于一些彼此之間沒(méi)有太大關(guān)聯(lián)的一些類(lèi)。
  • 通過(guò)接口轉(zhuǎn)換,將一個(gè)類(lèi)插入另一個(gè)類(lèi)系中。

2. 方法

  • 繼承或依賴(lài)。

3. 優(yōu)點(diǎn)

  • 可以讓任何兩個(gè)沒(méi)有關(guān)聯(lián)的類(lèi)一起運(yùn)行。
  • 增加了類(lèi)的透明性。我們?cè)L問(wèn)Target目標(biāo)角色,但具體實(shí)現(xiàn)都委托給了源角色,而這些對(duì)高層模塊是透明的,也是不需要關(guān)心的。
  • 提高了類(lèi)的復(fù)用度。源角色在原有的系統(tǒng)中還是可以正常使用,而在目標(biāo)角色中也可以充當(dāng)新的演員。
  • 靈活性非常好。什么時(shí)候不想要適配器了,直接刪掉就可以了,基本上就類(lèi)似一個(gè)靈活的構(gòu)件,想用就用,不想用就卸載。

4. 缺點(diǎn)

  • 過(guò)多使用適配器,會(huì)使系統(tǒng)非常零亂。
  • 由于Java至多繼承一個(gè)類(lèi),所以至多只能適配一個(gè)適配者類(lèi),而且目標(biāo)類(lèi)必須是抽象類(lèi)。

5. 使用場(chǎng)景

  • 有動(dòng)機(jī)地修改一個(gè)正常運(yùn)行的系統(tǒng)的接口。
  • 以前開(kāi)發(fā)的系統(tǒng)存在滿(mǎn)足新系統(tǒng)功能需求的類(lèi),但其接口同新系統(tǒng)的接口不一致。
  • 使用第三方提供的組件,但組件接口定義和自己要求的接口定義不同。

6. 應(yīng)用實(shí)例

  • 電源適配器。
  • Java中的[JDBC]

7. 注意事項(xiàng)

  • 只有碰到無(wú)法改變?cè)性O(shè)計(jì)和代碼的情況下,才考慮適配器模式。

三、適配器模式的擴(kuò)展

適配器模式(Adapter)可擴(kuò)展為雙向適配器模式,雙向適配器類(lèi)既可以把適配者接口轉(zhuǎn)換成目標(biāo)接口,也可以把目標(biāo)接口轉(zhuǎn)換成適配者接口,

1. UML結(jié)構(gòu)圖

雙適配模式.gif

2. 雙適配模式實(shí)現(xiàn)代碼

package adapter;
//目標(biāo)接口
interface TwoWayTarget
{
    public void request();
}
//適配者接口
interface TwoWayAdaptee
{
    public void specificRequest();
}
//目標(biāo)實(shí)現(xiàn)
class TargetRealize implements TwoWayTarget
{
    public void request()
    {       
        System.out.println("目標(biāo)代碼被調(diào)用!");
    }
}
//適配者實(shí)現(xiàn)
class AdapteeRealize implements TwoWayAdaptee
{
    public void specificRequest()
    {       
        System.out.println("適配者代碼被調(diào)用!");
    }
}
//雙向適配器
class TwoWayAdapter  implements TwoWayTarget,TwoWayAdaptee
{
    private TwoWayTarget target;
    private TwoWayAdaptee adaptee;
    public TwoWayAdapter(TwoWayTarget target)
    {
        this.target=target;
    }
    public TwoWayAdapter(TwoWayAdaptee adaptee)
    {
        this.adaptee=adaptee;
    }
    public void request()
    {
        adaptee.specificRequest();
    }
    public void specificRequest()
    {       
        target.request();
    }
}
//客戶(hù)端代碼
public class TwoWayAdapterTest
{
    public static void main(String[] args)
    {
        System.out.println("目標(biāo)通過(guò)雙向適配器訪問(wèn)適配者:");
        TwoWayAdaptee adaptee=new AdapteeRealize();
        TwoWayTarget target=new TwoWayAdapter(adaptee);
        target.request();
        System.out.println("-------------------");
        System.out.println("適配者通過(guò)雙向適配器訪問(wèn)目標(biāo):");
        target=new TargetRealize();
        adaptee=new TwoWayAdapter(target);
        adaptee.specificRequest();
    }
}

四、類(lèi)適配器和對(duì)象適配器的區(qū)別

從上面的內(nèi)容可以看出來(lái),類(lèi)適配器是類(lèi)間繼承,對(duì)象適配器是對(duì)象的合成關(guān)系,也可以說(shuō)是類(lèi)的關(guān)聯(lián)關(guān)系,這是兩者的根本區(qū)別。

? 由于對(duì)象適配器是通過(guò)類(lèi)間的關(guān)聯(lián)關(guān)系進(jìn)行耦合的,因此在設(shè)計(jì)時(shí)就可以做到比較靈活,而類(lèi)適配器就只能通過(guò)覆寫(xiě)源角色的方法進(jìn)行擴(kuò)展。

? 在實(shí)際項(xiàng)目中,對(duì)象適配器使用到的場(chǎng)景較多。

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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