1. 程式人生 > 實用技巧 >尚矽谷設計模式筆記-介面卡模式

尚矽谷設計模式筆記-介面卡模式

Table of Contents generated with DocToc

一、生活中的介面卡

每個國家使用的插座標準不同,比如泰國用的是兩孔的(歐標),中國用的是三孔的。

我們到泰國旅遊時,如果只帶了三孔插頭,則可以買個多功能轉換插頭【介面卡】,這樣就可以使用泰國的兩孔插座了。


二、程式中的介面卡模式

2.1 基本介紹

  1. 介面卡模式(Adapter Pattern)將某個類的介面轉換成客戶端期望的另一個介面表示,主的目的是相容性,讓原本因介面不匹配不能一起工作的兩個類可以協同工作。其別名為包裝器(Wrapper)
  2. 介面卡模式屬於結構型模式【並沒有產生新的物件】
  3. 主要分為三類:類介面卡模式、物件介面卡模式、介面介面卡模式

2.2 工作原理

  1. 介面卡模式:將一個類的介面轉換成另一種介面。讓原本介面不相容的類可以相容
  2. 從使用者的角度看不到被適配者,是解耦的
  3. 使用者呼叫介面卡轉化出來的目標介面方法,介面卡再呼叫被適配者的相關介面方法
  4. 使用者收到反饋結果,感覺只是和目標介面互動,如圖


三、類介面卡模式

基本介紹:Adapter類,通過繼承src類, 實現dst類介面,完成src->dst的適配。

3.1 應用例項

以生活中充電器的例子來講解介面卡,充電器本身相當於Adapter, 220V交流電
相當於src (即被適配者),我們的dst(即 目標)是5V直流電

3.2 類圖

我們手機需要5v的直流電,則呼叫5v直流電的介面,然後使用介面卡VoltageAdapter將220v的電壓轉為5v即可

3.3 java實現

  1. 首先實現220v電壓
//被適配類Source
public class Voltage220v {
    public int output220v(){
        int src = 220;
        System.out.println("輸出"+src+"伏特");
        return src;
    }
}
  1. 然後建立5v直流電介面
//適配介面
public interface Voltage5v {
    int output5v();
}
  1. 建立介面卡類,繼承voltage220v,實現voltage5v
//介面卡
public class VoltageAdapter extends Voltage220v implements Voltage5v{
    @Override
    public int output5v() {
        int source = output220v();
        int target = source / 44;
        return target;
    }
}
  1. 手機類
public class Phone{
    public void chargiing(Voltage5v voltage5v){
        if(voltage5v.output5v()==5){
            System.out.println("電壓為5v,可以充電");
        }
        else{
            System.out.println("電壓不合適,不可以充電");
        }
    }
}
  1. 呼叫:
public class Client {
    public static void main(String[] args) {
        System.out.println("===========類介面卡模式===========");
        Phone phone = new Phone();
        //VoltageAdapter相當於充電器
        phone.chargiing(new VoltageAdapter());
    }
}

輸出為:

=類介面卡模式=
輸出220伏特
電壓為5v,可以充電

3.4 總結

類介面卡模式注意事項和細節

  • Java是單繼承機制,所以類介面卡需要繼承src類這一 點算是一個缺點,因為這要
    求dst必須是介面,有一定侷限性;
  • src類 的方法在Adapter中都會暴露出來,也增加了使用的成本。
  • 由於其繼承了src類,所以它可以根據需求重寫src類的方法, 使得Adapter的靈
    活性增強了。

四、物件介面卡

物件介面卡模式介紹

  1. 基本思路和類的介面卡模式相同,只是將Adapter類作修改,不是繼承src類, 而
    是持有src類的例項,以解決相容性的問題。即:持有src類,實現dst類介面,
    完成src->dst的適配
  2. 根據“合成複用原則”,在系統中儘量使用關聯關係來替代繼承關係。
  3. 物件介面卡模式是介面卡模式常用的一種

只需要改動介面卡類VoltageAdapter,將繼承改為依賴

//介面卡
public class VoltageAdapter implements Voltage5v{
    
    private Voltage220v sourceV;

    public VoltageAdapter(Voltage220v sourceV) {
        this.sourceV = sourceV;
    }

    @Override
    public int output5v() {
        int target = 0;
        if(null != sourceV){
            int source = sourceV.output220v();
        	target = source / 44;
        }
        return target;
    }
}

然後改動Client

public class Client {
    public static void main(String[] args) {
        System.out.println("===========類介面卡模式===========");
        Phone phone = new Phone();
        //VoltageAdapter相當於充電器
        phone.chargiing(new VoltageAdapter(new Voltage220v()));
    }
}

五、介面介面卡模式

基本介紹:

  1. 一些書籍稱為:介面卡模式(Default Adapter Pattern)或預設介面卡模式。
  2. 不需要全部實現介面提供的方法時,可先設計一個抽象類實現介面,併為該接
    口中每個方法提供一一個預設實現(空方法),那麼該抽象類的子類可有選擇地覆
    蓋父類的某些方法來實現需求
  3. 適用於一個介面不想使用其所有的方法的情況。

5.1 類圖

我們不需要實現Interface中所有方法,只需要用匿名內部類的方式實現AbstractAdapter中的部分方法即可

5.2 java實現

  1. 基本介面
public interface BaseInterface {
    void operation1();
    void operation2();
    void operation3();
}
  1. 介面卡(空實現)
public abstract class AbstractAdapter implements BaseInterface{
    public void operation1() {
        
    }
    
    public void operation2() {

    }
    
    public void operation3() {

    }
}
  1. 使用介面卡
public class Client {
    public static void main(String[] args) {
        //匿名內部類重寫部分方法
        AbstractAdapter abstractAdapter = new AbstractAdapter(){
            @Override
            public void operation1() {
                System.out.println("重寫方法一");
            }
        };
        abstractAdapter.operation1();
    }
}