Java設計模式6:介面卡模式
一、介面卡模式定義:
介面卡模式說的是,可以把一個類的介面變換成客戶端所期待的另一種介面,使得原本因介面不匹配而無法在一起工作的兩個類可以一起工作。
舉個例子:比方說我有一個檯燈,其插頭是標準的兩相的交流電插頭,即陽極、陰極。我旅遊到了一個地方想用自己的檯燈,但發現旅館裡面只有三相的插頭,即在陽極、陰極的基礎上還多了一個地級。這時候怎麼辦呢,一個兩相到三相的轉換器(介面卡)就能解決這個問題了,而這正是本模式所做的事情。
二、適用場景
1,系統需要使用現有的類,但現有的類卻不相容。 2,需要建立一個可以重複使用的類,用於一些彼此關係不大的類,並易於擴充套件,以便於面對將來會出現的類。 3,需要一個統一的輸出介面,但是輸入型別卻不可預知。
三、模式解釋:
Source:需要被適配的類、介面、物件,即Datas。 Target:需要得到的介面,也就是我們期待得到的介面。 Adapter:介面卡類,協調Source和Target,使兩者能夠協同工作。
四、程式碼示例:
先假設系統存在一個現有的類ClassSource:
/** * <pre> * @author : orange * @e-mail : [email protected] * @time : 2018/9/30 14:46 * @desc : 源類 * @version: 1.0 * </pre> */ @Data public class ClassSource { private Map<String, String> baseInfo; }
正常模式下我們客戶端這樣去資料:
/** * <pre> * @author : orange * @e-mail : [email protected] * @time : 2018/9/30 15:01 * @desc : * @version: 1.0 * </pre> */ public class Client { public static void main(String[] args){ //先新增一些資料 ClassSource classSource = new ClassSource(); Map<String,String> map = new HashMap<>(); map.put("name","orange"); map.put("mobile","110"); classSource.setBaseInfo(map); //客戶端取資料 String name = classSource.getBaseInfo().get("name"); String mobile = classSource.getBaseInfo().get("mobile"); } }
有一天,基於某種原因(也許是業務更改的原因,也許是系統間資料交換的原因等),你需要按照如下介面的方式取資料:
/**
* <pre>
* @author : orange
* @e-mail : [email protected]
* @time : 2018/9/30 14:54
* @desc :目標介面
* @version: 1.0
* </pre>
*/
public interface ClassTarget {
String getBaseInfoName();
String getBaseInfoMobile();
}
那麼我們就再加一個介面卡類,將一個既定的類轉換成按照目標介面的所期望的行為形式。
/**
* <pre>
* @author : orange
* @e-mail : [email protected]
* @time : 2018/9/30 14:55
* @desc : 類介面卡中的轉換器
* @version: 1.0
* </pre>
*/
public class ClassAdapter extends ClassSource implements ClassTarget {
@Override
public String getBaseInfoName() {
return super.getBaseInfo().get("name");
}
@Override
public String getBaseInfoMobile() {
return super.getBaseInfo().get("mobile");
}
}
可以由上看出,類介面卡模式是指:定義一個類,將一個已經存在的類,轉換成目標介面所期望的行為形式。
在具體的實現過程中,又可以基於其實現層次是類層次還是物件層次,將其分為類介面卡和物件介面卡。如上所寫的是類介面卡。
物件介面卡使用組合代替繼承,將源角色類視為介面卡角色的屬性:
物件介面卡:
/**
* <pre>
* @author : orange
* @e-mail : [email protected]
* @time : 2018/9/30 15:06
* @desc : 物件介面卡轉換器
* @version: 1.0
* </pre>
*/
public class ObjectAdapter implements ClassTarget {
private ClassSource classSource;
public ObjectAdapter(){
}
public ObjectAdapter(ClassSource classSource){
this.classSource = classSource;
}
@Override
public String getBaseInfoName() {
return classSource.getBaseInfo().get("name");
}
@Override
public String getBaseInfoMobile() {
return classSource.getBaseInfo().get("mobile");
}
}
總結:
介面卡模式在JDK中的應用及解讀
寫了這麼多種設計模式了,可能介面卡模式是最不好理解的一種寫法。介面卡模式的寫法很多,寫法越多、模式越不好理解,就越應該抓住模式的核心,像介面卡模式的核心就是"把一個類的介面變換成客戶端所期待的另一種介面",所以我們可以看一下InputStreaReader和OutputStreamWriter。
比方說InputStreamReader吧,建立InputStreamReader物件的時候必須在建構函式中傳入一個InputStream例項,然後InputStreamReader的作用就是將InputStream適配到Reader。很顯然,介面卡就是InputStreamReader,源角色就是InputStream代表的例項物件,目標介面就是Reader類。
OutputStreamWriter也是類似的方式。
介面卡模式的優缺點
優點
1、有更好的複用性。系統需要使用現有的類,但此類介面不符合系統需要,通過介面卡模式讓這些功能得到很好的複用
2、有更好的擴充套件性。實現介面卡,可以呼叫自己開發的功能
缺點
過多使用介面卡會使得系統非常凌亂,明明呼叫的是A介面,內部卻被適配成了B介面。因此除非必要,不推薦使用介面卡,而是直接對系統重構