不學無數——介面卡模式

不學無數的程式設計師發表於2018-10-11

介面卡模式

智者千慮必有一失,愚者千慮必有一得

在我們開發過程中也會經常碰到一些給原有的系統加一些功能,所以不管前期我們呢可行性、需求分析和系統設計處理的多好,隨著時間的推移,總會出一些“意外”。因此我們該如何處理掉這些“意外”呢?聰明的程式設計師們就想到了許多的補救模式,其中介面卡模式就是補救模式中的一種。這種模式可以能夠讓你從因為業務的快速迭代而引發程式碼改變的煩惱中解脫出來。

適配模式的定義

將一個類的介面變換成客戶端所期待的另一種介面,從而使原本因為介面不匹配而無法在一起工作的兩個類能夠一起工作

介面卡模式有三個角色

  • Source:需要被適配的介面或者物件,你想把誰轉換成目標角色,那麼這個“誰”就是Source角色
  • Target:需要得到的介面或者物件,即適配完Source得到的介面或者物件,我們所期望的介面
  • Adapter:介面卡,協調Source和Target使兩個能夠一起工作。通過繼承或者是類關聯的方式

繼承介面卡

介面卡模式有兩種體現形式,一種是通過繼承來表現,一種是通過關聯物件來表現,下面給演示下繼承表現的介面卡。

介面卡模式類圖

下面我們寫一個簡單的介面卡模式的例子,如下所示

Target介面程式碼

interface Target{
    public void request();
}

複製程式碼

實現了Target介面的類

class RealTarget implements Target{
    @Override
    public void request() {
        System.out.println("I am Target");
    }
}

複製程式碼

Source源目標類

class Source{
    public void doSomething(){
        System.out.println("I am Source");
    }
}

複製程式碼

接下來核心的角色要出現了就是Adapter

class Adapter extends Source implements Target{
    @Override
    public void request() {
        super.doSomething();
    }
}

複製程式碼

接下來我們可以進行呼叫試試

public class AdapterTest {
    public static void main(String[] args) {
        Target target = new RealTarget();
        target.request();
        Target target2 = new Adapter();
        target2.request();
    }
}

複製程式碼

列印如下

I am Target
I am Source
複製程式碼

物件介面卡

我們上面使用的是通過繼承來使用介面卡模式,還有一種做法就是將原有的繼承關係變更為關聯關係就可以了。

物件介面卡和類介面卡的區別在於:類介面卡是通過繼承來表現的,而物件介面卡是物件的合成關係,也可以說是類的關聯關係,這是兩者的根本區別。兩個都會在專案中用到,由於物件介面卡是通過類間的關聯關係進行耦合的,因此在設計的時候就比較靈活。而類介面卡只能通過覆寫源角色的方法進行擴充套件。因此在實際專案中,物件介面卡的使用場景比較多。

我們還是先來看一下物件介面卡的類圖如下

物件介面卡類圖

然後寫一個通用的例子

現在介面Target

interface Target2{
    public void printSource1();
    public void printSource2();
}

複製程式碼

然後有Adapter

class Adapter implements Target{

    private Source1 source1;
    private Source2 source2;

    public Adapter(){
        source1 = new Source1();
        source2 = new Source2();
    }

    @Override
    public void printSource1() {
        source1.print();
    }

    @Override
    public void printSource2() {
        source2.print();
    }

}

複製程式碼

然後兩個Source

class Source1{
    public void print(){
        System.out.println("I am Source1");
    }
}

class Source2{
    public void print(){
        System.out.println("I am Source2");
    }
}

複製程式碼

然後進行呼叫如下

public static void main(String[] args) {
    Target2 target2 = new Adapter2();
    target2.printSource1();
    target2.printSource2();
}
複製程式碼

列印如下

I am Source1
I am Source2
複製程式碼

這樣在以後增加了需求以後,只需要重新寫介面卡即可,上層程式碼不用動。

介面卡的優點

  • 介面卡模式可以讓兩個沒有任何關係的類在一起執行,只要介面卡這個角色即可。
  • 增加了類的透明性:我們訪問的是Target目標角色,但是具體的實現都是委託給了源角色,而這些對高層次的模組是透明的,也是它不需要關心的。
  • 提高了類的複用:源角色在原有的系統中還是能夠繼續使用,而在目標角色中也可以充當新的角色。
  • 靈活性好:如果某一天突然一個介面卡不需要了,那麼只要刪除即可,基本上就類似於一個靈活的構件,想用就用。

介面卡模式的使用場景

介面卡應用的場景只需要記住一點就夠了:當你有動機修改一個已經投產中的介面時,介面卡模式是最適合你的模式。比如系統擴充套件了,需要使用一個已有或者是新建的類,但是這個類又不符合系統的介面,怎麼辦?這時候就可以使用介面卡模式。

參考文章

相關文章