適配器模式
適配器模式說的是,可以把一個類的接口變換成客戶端所期待的另一種接口,使得原本因接口不匹配而無法在一起工作的兩個類可以一起工作。
適配器模式的用途
適配器模式的用途,在網上找了一幅圖,挺形象的:
比方說我有一個台燈,其插頭是標准的兩相的交流電插頭,即陽極、陰極。我旅游到了一個地方想用自己的台燈,但發現旅館里面只有三相的插頭,即在陽極、陰極的基礎上還多了一個地級。這時候怎么辦呢,一個兩相到三相的轉換器(適配器)就能解決這個問題了,而這正是本模式所做的事情。
類適配器
適配器模式分兩種,類適配器和對象適配器。先講類適配器,類適配器把適配的類的API轉換成目標類的API,類適配器所涉及的角色有:
1、目標角色
這是所期待得到的接口
2、源角色
現在需要適配的接口
3、適配器角色
模式的核心,適配器把源接口轉換成目標接口
類適配器示例
目標接口,期待得到sampleOperation1()和sampleOperation2()兩個方法:
public interface ClassTarget { /** 這是源類ClassAdaptee也有的方法 */ public void sampleOperation1(); /** 這是源類ClassAdaptee沒有的方法 */ public void sampleOperation2(); }
源角色,只有一個sampleOperation1()方法:
public class ClassAdaptee { public void sampleOperation1(){} }
適配器角色擴展了ClassAdaptee,同時又實現了目標接口。由於ClassAdaptee沒有提供sampleOperation()2方法,而目標接口又要求這個方法,因此適配器角色實現了這個方法:
public class ClassAdapter extends ClassAdaptee implements ClassTarget { public void sampleOperation2() { // 相關代碼 } }
可能有些人一遍看下來不是很明白,這怎么就是一個適配器模式了,解釋一下:
1、客戶端期待一個接口ClassTarget有sampleOperation1()和sampleOperation2()這兩個方法
2、現在我一個類ClassAdaptee里面只有一個sampleOperation1()方法
3、既然ClassTarget要兩個方法,我現在的ClassAdaptee只有一個方法怎么辦?搞一個適配器,多變出一個sampleOperation2(),就符合ClassTarget的標准了,由於適配器是ClassTarget接口的實現類,所以可以直接使用適配器作為ClassTarget
對象適配器示例
還是一樣的,一個目標接口,期待得到sampleOperation1()和sampleOperation2()方法:
public interface ObjectTarget { public void sampleOperation1(); public void sampleOperation2(); }
源角色,只有一個sampleOperation1()方法:
public class ObjectAdaptee { public void sampleOperation1(){} }
和類適配器不同的是,對象適配器采用了委派關系將源角色與適配器角色關聯:
public class ObjectAdapter { private ObjectAdaptee objectAdaptee; public ObjectAdapter(ObjectAdaptee objectAdaptee) { this.objectAdaptee = objectAdaptee; } public void sampleOperation1() { this.objectAdaptee.sampleOperation1(); } public void sampleOperation2(){} }
適配器模式在JDK中的應用及解讀
寫了這么多種設計模式了,可能適配器模式是最不好理解的一種寫法。適配器模式的寫法很多,寫法越多、模式越不好理解,就越應該抓住模式的核心,像適配器模式的核心就是"把一個類的接口變換成客戶端所期待的另一種接口",所以我們可以看一下InputStreaReader和OutputStreamWriter。
比方說InputStreamReader吧,創建InputStreamReader對象的時候必須在構造函數中傳入一個InputStream實例,然后InputStreamReader的作用就是將InputStream適配到Reader。很顯然,適配器就是InputStreamReader,源角色就是InputStream代表的實例對象,目標接口就是Reader類。
OutputStreamWriter也是類似的方式。
適配器模式的優缺點
優點
1、有更好的復用性。系統需要使用現有的類,但此類接口不符合系統需要,通過適配器模式讓這些功能得到很好的復用
2、有更好的擴展性。實現適配器,可以調用自己開發的功能
缺點
過多使用適配器會使得系統非常凌亂,明明調用的是A接口,內部卻被適配成了B接口。因此除非必要,不推薦使用適配器,而是直接對系統重構