首頁 >Java >java教程 >Java中適配器模式(Adapter)是什麼?適配器模式(詳解)

Java中適配器模式(Adapter)是什麼?適配器模式(詳解)

青灯夜游
青灯夜游轉載
2018-10-18 16:14:198406瀏覽

這篇文章帶給大家的內容是Java中適配器模式(Adapter)是什麼?適配器模式(詳解)。有一定的參考價值,有需要的朋友可以參考一下,希望對你們有幫助。

目的:把來源類型適配為目標類型,以適應客戶端(Client)的需求;這裡我們把目標介面的呼叫方視為客戶端

使用場景:需要對類型進行由來源類型轉換到目標類型的場景中

前置條件已有客戶端

//Client 一个调用目标接口的方法
Class ClientInvoking {

    static void invoke(TargetInterface target) {
        String value = target.getMark();
        System.out.println(value);
    }

}

常用的幾種模式

模式一:存在目標接口,且存在已有方法

//目标接口
public interface TargetInterface {
    
    public String getMark();

    public String getInfo();

}
//已有类及方法
public class ExistClass {

    public String sayHello() {
        return "Hello";
    }
      
    public String sayWorld() {
        return "World";
    }
}

我們假設ExistClass返回的字串正好是我們的客戶端需要用到的,但客戶端需要的是透過一個TargetInterface類型的物件來獲取,因此我們需要想辦法對已有類別進行適配,使其能夠滿足客戶端的需求;該模式下存在兩種應用方案:

#方案1.類別適配器模式

//适配器
public class ClassAdapter extends ExistClass implements TargetInterface {
    
    public int getMark() {
        String value = this.sayHello();
        return value;
    }
    
    public int getInfo() {
        String value = this.sayWorld();
        return value;
    }
    
}
//客户端调用
TargetInterface target = new ClassAdapter();
ClientInvoking.invoke(target);

由Java介面的概念可知,ClassAdapter作為TargetInterface的實作類,能夠向上轉型為TargetInterface類型,適應了客戶端的需求。

方案2.物件適配器模式

//适配器
public class ClassAdapter implements TargetInterface {
    
    private ExistClass exist;
    
    public ClassAdapter(ExistClass existClass) {
        this.exist = existClass;
    }
    
    public int getMark() {
        String value = exist.sayHello();
        return value;
    }
    
    public int getInfo() {
        String value = exist.sayWorld();
        return value;
    }
    
}
//客户端调用
TargetInterface target = new ClassAdapter(new ExistClass());
ClientInvoking.invoke(target);

此方案與類別適配器模式類似,只是不採用繼承而採用持有物件的方式,更加靈活,擴展性更強。

模式二:不存在目標接口,但是存在目標類,且存在已有方法

我們先對前置條件中的客戶端進行改造,如下:

Class ClientInvoking {

    static void invoke(TargetClass target) {
        String value = target.getMark();
        System.out.println(value);
    }

}

改造後,invoke方法需要一個TargetClass類別的物件作為參數;下面是目標類別和已有類別

//目标类
public class Class {
    
    public String getMark() {
        return "yes";
    }

    public String getInfo() {
        return "no";
    }

}
//已有类及方法
public class ExistClass {

    public String sayHello() {
        return "Hello";
    }
      
    public String sayWorld() {
        return "World";
    }
}

我們假設ExistClass回傳的字串剛好是我們的客戶端需要用到的,且客戶端中需要的TargetClass物件的內容已經過時,因此我們需要相辦法對ExistClass進行適配,以適應客戶端的需求;

//适配器
public class ClassAdapter extends TargetClass {
    
    private ExistClass exist;
    
    public ClassAdapter(ExistClass existClass) {
        this.exist = existClass;
    }
    
    public int getMark() {
        String value = exist.sayHello();
        return value;
    }
    
    public int getInfo() {
        String value = exist.sayWorld();
        return value;
    }
    
}
//客户端调用
TargetClass target = new ClassAdapter(new ExistClass());
ClientInvoking.invoke(target);

在該種模式下,設計到兩個類,且最後要進行向上轉型,根據Java的單繼承機制,我們只能透過持有物件的形式,即物件適配器模式。

模式三:預設適配器模式

該模式中,不存在明確的目標類型,而僅有來源類型;之所以需要用到這個,往往是因為來源類型中提供了太多我們並不需要的東西,我們需要透過適配器模式進行客製化。以WindowListener作為例子講解:

//WindowListener源码
public interface WindowListener extends EventListener {
    public void windowOpened(WindowEvent e);
    public void windowClosing(WindowEvent e);
    public void windowClosed(WindowEvent e);
    ...
}
//添加监听器的例子
Frame frame = new Frame();
frame.addWindowListener(new WindowListener() {
    @Override    
    public void windowOpened(WindowEvent e) {
            
    }

    @Override    
    public void windowClosing(WindowEvent e) {

    }

    @Override    
    public void windowClosed(WindowEvent e) {

    }
    ...
})

這樣的程式碼,看起來很繁瑣;比如說我只需要監聽正在關閉的事件,卻產生了許多與此無關的模板程式碼,降低了程式碼的可讀性,鑑於此,我們來做下定制,只監聽一個接口;

我們首先提供一個抽象類別實現了該接口,並為所有監聽器提供空實現;然後再用抽象類別的子類別重寫視窗正在關閉的監聽器的實現,程式碼如下:

//适配器
public abstract ListenerAdapter implements WindowListener {
    public void windowOpened(WindowEvent e) {}
    public void windowClosing(WindowEvent e) {}
    public void windowClosed(WindowEvent e) {}
    ...
}
//重写方法
public class OverrideWindowClosing extends ListenerAdapter {
    
    @Override    
    public void windowClosing(WindowEvent e) {        
       //TODO    
    }
    
}
//客户端调用
frame.addWindowListener(new OverrideWindowClosing());

該方式簡化了接口,提高了程式碼可讀性。最重要的是,我們實現了對介面的定制,可以只做自己關心的事情。

總結:以上就是這篇文章的全部內容,希望能對大家的學習有所幫助。更多相關教學請造訪Java影片教學java開發圖文教學bootstrap影片教學

以上是Java中適配器模式(Adapter)是什麼?適配器模式(詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除