設計模式-介面卡模式

Nobody A發表於2020-11-10

定義

介面卡模式將一個類的介面,轉換成客戶端期待的另一個介面。

比如我們想用蘋果的充電線給安卓充電。但是安卓的充電介面(type-c)跟蘋果(lightning)的不一樣,所以就需要一個介面卡,將安卓的type-c介面轉換成蘋果的lightning介面,這樣就能用蘋果的充電線給安卓充電了。

Adapter.jpg
Adapter.jpg

圖中玫瑰金色的就是介面卡。

角色

  • 目標(Target):即期望的介面。
  • 介面卡(Adapter):用於將源介面轉換成目標介面。
  • 被適配者(Adaptee):即源介面。

類圖

介面卡模式類圖.png
介面卡模式類圖.png

示例

public class AdapterDP {
    public static void main(String[] args) {
        AppleLightning appleLighting = new AppleLightning();
        System.out.println("use lightning to charge");
        appleLighting.chargeWithLightning();

        System.out.println('\n' + "use type-c to charge");
        AndroidTypeC androidTypeC = new AndroidTypeC();
        androidTypeC.chargeWithTypeC();

        System.out.println('\n' + "use lightning to charge");
        Lightning adapter = new Adapter(androidTypeC);
        adapter.chargeWithLightning();
    }


}

interface Lightning {
    void chargeWithLightning();
}

class AppleLightning implements Lightning {
    public void chargeWithLightning() {
        System.out.println("charging iPhone...");
    }
}

class AndroidTypeC {
    public void chargeWithTypeC() {
        System.out.println("charging android...");
    }
}

class Adapter implements Lightning {
    public AndroidTypeC androidTypeC;

    public Adapter(AndroidTypeC androidTypeC) {
        this.androidTypeC = androidTypeC;
    }

    public void chargeWithLightning() {
        androidTypeC.chargeWithTypeC();
    }

}複製程式碼

輸出

use lightning to charge
charging iPhone...

use type-c to charge
charging android...

use lightning to charge
charging android...複製程式碼

注:以上的例子是物件介面卡模式,還有另一種介面卡模式叫類介面卡模式,這裡不再贅述。

介面卡模式在Hadoop原始碼中的應用

Hadoop作為廣泛應用的大資料元件,其本質是一個分散式系統,在分散式系統中,各個節點之間的通訊和互動是必不可少的,為此,Hadoop實現了一套自己的RPC框架,該RPC框架預設使用Protocol Buffer作為序列化工具。

ClientProtocol協議定義了HDFS Client和NameNode互動的所有方法,但是ClientProtocol協議中方法的引數是無法在網路中傳輸的,需要對引數進行序列化操作,所以HDFS又定義了ClientNamenodeProtocolPB協議,該協議包含了ClientProtocol定義的所有方法,但是引數卻是使用protobuf序列化後的格式。

ClientNamenodeProtocolTranslatorPB類作為Client側的介面卡類,實現了ClientProtocol介面,它內部擁有一個實現了ClientNamenodeProtocolPB介面的物件,可以將ClientProtocol呼叫適配成ClientNamenodeProtocolPB呼叫。以rename()呼叫為例,ClientNamenodeProtocolPB將rename(String, String)呼叫中的兩個String引數序列化成一個RenameRequestProto物件,然後呼叫ClientNamenodeProtocolPB物件的rename(RenameRequestProto)方法,這樣就完成了ClientProtocol介面到ClientNamenodeProtocolPB介面的適配。

在該例子中,ClientNamenodeProtocolTranslatorPB類為介面卡,ClientProtocol為目標介面(這裡的目標是對客戶端來說的),ClientNamenodeProtocolPB為源介面

可進入我的部落格檢視原文

歡迎關注公眾號: FullStackPlan 獲取更多幹貨
歡迎關注公眾號: FullStackPlan 獲取更多幹貨

相關文章