12/24 設計模式之介面卡模式 Adapter Pattern

蘇小林發表於2020-04-03

類別:結構型設計模式

目的:將歷史遺留程式碼(通常是一個library)/三方程式碼轉換成一個新介面,使得可以在使用這個新介面的專案中使用

完整程式碼參考:1drv.ms/u/s!AquRvPz…

典型場景

這裡拿一個系統中的支付模組舉例,一個支付模組會對接多個支付比如微信,支付寶等

基本事實

在現有程式碼中,已在使用一種支付方式處理訂單,對應的支付介面Pay.java參考如下

public interface Pay {
    void setAmount(Integer amount);
    void makePayment();
}
複製程式碼

上面這個介面的實現PayImpl.java

public class PayImpl implements Pay {
    @Override
    public void setAmount(Integer amount) {
        System.out.println("set pay impl");
    }

    @Override
    public void makePayment() {
        System.out.println("make payment");
    }
}
複製程式碼

serviceMyService.java中使用支付方式處理訂單,參考如下:

public class MyService {
    public void processOrder(Pay pay) {
        pay.setAmount(1);
        pay.makePayment();
    }
}
複製程式碼

呼叫參考

var myservice = new MyService();
var pay = new PayImpl();
myservice.processOrder(pay);
複製程式碼

執行效果如下:

-w323
可以看到現有支付呼叫是ok的

接入一個新的支付方式

新的支付方式比如Pay1的介面Pay1.service參考如下:

public interface Pay1 {
    void init();
    void setPrice(Integer amount);
    void processPay();
}
複製程式碼

對應實現Pay1Impl.java

public class Pay1Impl implements Pay1 {
    @Override
    public void init() {
        System.out.println("pay1 init");
    }

    @Override
    public void setPrice(Integer amount) {
        System.out.println("pay1 set amount");
    }

    @Override
    public void processPay() {
        System.out.println("pay1 make payment");
    }
}
複製程式碼

和現存支付介面對比

Pay1.java Pay.java
init 不存在
setPrice setAmount
processPay makePayment

可以看到被使用的第三方支付方式的介面和專案中現存的不一樣,這樣就不能在MyService中直接使用了(參考編輯器的提示)

-w745
這種情況就可以使用適配模式了

模式實現

就是將需要新增的三方支付方式Pay1適配成目前專案需要的Pay,新增一個類比如Pay1Adapter進行介面轉換

Pay1Adapter.java參考如下:

public class Pay1Adapter implements Pay {
    private Pay1 pay1;
    
    public Pay1Adapter(Pay1 pay1) {
        this.pay1 = pay1;
    }

    @Override
    public void setAmount(Integer amount) {
        pay1.init();
        pay1.setPrice(amount);
    }

    @Override
    public void makePayment() {
        pay1.processPay();
    }
}
複製程式碼

適配效果如下

-w551

可以看到經過適配後,Pay1可以在需要Pay介面的專案中使用了

這個將Pay1介面轉成Pay介面的Pay1Adapter就是介面卡

UML

-w721

為什麼要使用介面卡

  1. 儘可能使用最少的程式碼複用三方程式碼
  2. 避免直接修改三方程式碼

一些注意的點

一般三方sdk不會為某個系統單獨進行適配,就需要自行進行適配了

參考資料

  1. www.geeksforgeeks.org/adapter-pat…

相關文章