1、簡介
通常,客戶端通過類的接口訪問它提供的服務,有時,現有的類可以提供客戶類的功能需要,但是它所提供的接口不一定是客戶類所期望的。在這種情況下,現有的接口需要轉化為客戶類期望的接口,這樣保證了對現有類的重用,于是就需要用到適配器模式。適配器模式(Adapter)把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作,這種模式又稱為轉換器模式、變壓器模式、包裝(Wrapper)模式等。
模式所涉及的角色有:
目標(Target)角色:所期待得到的接口。
源(Adaptee)角色: 需要適配的接口。
適配器(Adapter)角色:適配器把源接口轉換成目標接口,根據這一角色的實現不同,可分為
類適配器(Class Adapter)和
對象適配器(Object Adapter)。
類適配器是通過繼承類適配者類(Adaptee Class)實現的,另外類適配器實現客戶類所需要的接口。當客戶對象調用適配器類方法的時候,適配器內部調用它所繼承的適配者的方法。
對象適配器包含一個適配器者的引用(reference),與類適配器相同,對象適配器也實現了客戶類需要的接口。當客戶對象調用對象適配器的方法的時候,對象適配器調它所包含的適配器者實例的適當方法。
適配器模式的用意是將接口不同而功能相同或者相近的兩個接口加以轉換,包括適配器角色補充一些源角色沒有但目標接口需要的方法。但不要誤以為適配器模式就是為了補充源角色沒有的方法而準備的。
類適配器(Class Adapter)
|
對象適配器(Object Adapter) |
基于繼承概念 |
利用對象合成 |
可以重載適配者的方法 |
不太容易重載適配者的方法 |
如果需要改變多個已有的子類的接口,就要針對每一個子類做一個適配器類,而這不太實際。
如果源中有大量的方法,使用類的適配器模式則比較容易(不需要一一寫出源類中的方法,而對象的適配器模式則要一一寫出目標角色中的方法,如缺省適配器)
|
可以把多種不同的源適配到同一個目標,換言之,同一個適配器可以把源類和它的子類都適配到目標接口。
增加的新方法可以同時適用所有的源。
|
2、使用場景及能解決的問題
系統需要使用現有的類,而此類的接口不符合系統的需要。
想要建立一個可以重復使用的類,用于與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作。這些源類不一定有 很復雜的接口。
類或方法的作用相同但名稱不同的類或方法之間進行適配。
3、類圖
4、實例
首先看看我們需要達成的目標類:
package adapter;
public interface MyTarget {
public void request();
public void specRequest();
}
在看看已經有的適配者:
package adapter;
public class Adaptee {
public void specRequest() {
System.out.println("this is specRequest.");
}
}
接下來是我們的核心——適配器,包括類適配器和對象適配器兩種實現方式:
package adapter;
public class ClassAdapter extends Adaptee implements MyTarget {
public void request() {
System.out.println("this is request");
}
}
package adapter;
public class ObjectAdapter implements MyTarget {
public void request(){
System.out.println("this is request");
}
public void specRequest(){
adaptee.specRequest();
}
private Adaptee adaptee = new Adaptee();
}
最后是調用的Client:
package adapter;
public class Client {
private static MyTarget ctarget = new ClassAdapter();
private static MyTarget otarget = new ObjectAdapter();
public static void main(String args[]){
ctarget.request();
ctarget.specRequest();
otarget.request();
otarget.specRequest();
}
}
5、缺省的適配器模式
缺省適配模式(Default Adapter Pattern)為一個接口提供缺省實現,這樣子類型可以從這個缺省實現進行擴展,而不必從原有接口進行擴展。
適配器模式的用意是要改變源的接口,以便與目標類的接口相容。缺省適配的用意稍有同,它是為了方便建立一個不平庸的適配器類而提供的一種平庸實現(就是為接口提供空的實現)。
在任何時候,如果不準備實現一個接口的所有方法時(一般在定義一個大的接口時都應該提供它的缺省適配類),就可以制造一個抽象類,給出所有方法的平庸的具體實現。這樣,從這個抽象類再繼承下去的子類就不必實現所有的方法了。缺省適配模式的中心是一個缺省適配類。這個類應當是抽象類。