結(jié)構(gòu)模式之Adapter——適配器模式
1、簡介通常,客戶端通過類的接口訪問它提供的服務(wù),有時,現(xiàn)有的類可以提供客戶類的功能需要,但是它所提供的接口不一定是客戶類所期望的。在這種情況下,現(xiàn)有的接口需要轉(zhuǎn)化為客戶類期望的接口,這樣保證了對現(xiàn)有類的重用,于是就需要用到適配器模式。適配器模式(Adapter)把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作,這種模式又稱為轉(zhuǎn)換器模式、變壓器模式、包裝(Wrapper)模式等。
模式所涉及的角色有:
目標(biāo)(Target)角色:所期待得到的接口。
源(Adaptee)角色: 需要適配的接口。
適配器(Adapter)角色:適配器把源接口轉(zhuǎn)換成目標(biāo)接口,根據(jù)這一角色的實現(xiàn)不同,可分為類適配器(Class Adapter)和對象適配器(Object Adapter)。
類適配器是通過繼承類適配者類(Adaptee Class)實現(xiàn)的,另外類適配器實現(xiàn)客戶類所需要的接口。當(dāng)客戶對象調(diào)用適配器類方法的時候,適配器內(nèi)部調(diào)用它所繼承的適配者的方法。
對象適配器包含一個適配器者的引用(reference),與類適配器相同,對象適配器也實現(xiàn)了客戶類需要的接口。當(dāng)客戶對象調(diào)用對象適配器的方法的時候,對象適配器調(diào)它所包含的適配器者實例的適當(dāng)方法。
適配器模式的用意是將接口不同而功能相同或者相近的兩個接口加以轉(zhuǎn)換,包括適配器角色補充一些源角色沒有但目標(biāo)接口需要的方法。但不要誤以為適配器模式就是為了補充源角色沒有的方法而準(zhǔn)備的。
類適配器(Class Adapter) |
對象適配器(Object Adapter) |
基于繼承概念 | 利用對象合成 |
可以重載適配者的方法 | 不太容易重載適配者的方法 |
如果需要改變多個已有的子類的接口,就要針對每一個子類做一個適配器類,而這不太實際。 如果源中有大量的方法,使用類的適配器模式則比較容易(不需要一一寫出源類中的方法,而對象的適配器模式則要一一寫出目標(biāo)角色中的方法,如缺省適配器) |
可以把多種不同的源適配到同一個目標(biāo),換言之,同一個適配器可以把源類和它的子類都適配到目標(biāo)接口。 增加的新方法可以同時適用所有的源。 |
2、使用場景及能解決的問題
系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要。
想要建立一個可以重復(fù)使用的類,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類,包括一些可能在將來引進(jìn)的類一起工作。這些源類不一定有 很復(fù)雜的接口。
類或方法的作用相同但名稱不同的類或方法之間進(jìn)行適配。
3、類圖

4、實例
首先看看我們需要達(dá)成的目標(biāo)類:
package adapter;
public interface MyTarget {
public void request();
public void specRequest();
}
在看看已經(jīng)有的適配者:public interface MyTarget {
public void request();
public void specRequest();
}
package adapter;
public class Adaptee {
public void specRequest() {
System.out.println("this is specRequest.");
}
}
接下來是我們的核心——適配器,包括類適配器和對象適配器兩種實現(xiàn)方式: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");
}
}
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();
}
最后是調(diào)用的Client:public class ObjectAdapter implements MyTarget {
public void request(){
System.out.println("this is request");
}
public void specRequest(){
adaptee.specRequest();
}
private Adaptee adaptee = new Adaptee();
}
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();
}
}
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)為一個接口提供缺省實現(xiàn),這樣子類型可以從這個缺省實現(xiàn)進(jìn)行擴展,而不必從原有接口進(jìn)行擴展。
適配器模式的用意是要改變源的接口,以便與目標(biāo)類的接口相容。缺省適配的用意稍有同,它是為了方便建立一個不平庸的適配器類而提供的一種平庸實現(xiàn)(就是為接口提供空的實現(xiàn))。
在任何時候,如果不準(zhǔn)備實現(xiàn)一個接口的所有方法時(一般在定義一個大的接口時都應(yīng)該提供它的缺省適配類),就可以制造一個抽象類,給出所有方法的平庸的具體實現(xiàn)。這樣,從這個抽象類再繼承下去的子類就不必實現(xiàn)所有的方法了。缺省適配模式的中心是一個缺省適配類。這個類應(yīng)當(dāng)是抽象類。
posted on 2008-06-19 16:49 云淡風(fēng)清 閱讀(397) 評論(0) 編輯 收藏 所屬分類: Design Patterns