1. 程式人生 > >Java設計模式6:介面卡模式

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介面。因此除非必要,不推薦使用介面卡,而是直接對系統重構