介面卡模式
介面卡模式說的是,可以把一個類的介面變換成客戶端所期待的另一種介面,使得原本因介面不匹配而無法在一起工作的兩個類可以一起工作。
介面卡模式的用途
介面卡模式的用途,在網上找了一幅圖,挺形象的:
比方說我有一個檯燈,其插頭是標準的兩相的交流電插頭,即陽極、陰極。我旅遊到了一個地方想用自己的檯燈,但發現旅館裡面只有三相的插頭,即在陽極、陰極的基礎上還多了一個地級。這時候怎麼辦呢,一個兩相到三相的轉換器(介面卡)就能解決這個問題了,而這正是本模式所做的事情。
類介面卡
介面卡模式分兩種,類介面卡和物件介面卡。先講類介面卡,類介面卡把適配的類的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介面。因此除非必要,不推薦使用介面卡,而是直接對系統重構