設計模式【6.2】-- 再聊聊介面卡模式

第十六封發表於2021-12-14

這裡說的介面卡不是通常所說的類介面卡,物件介面卡,介面介面卡,這裡實現的是把所有的類進行統一管理的介面卡。如需要查詢設計模式的三種主要介面卡模式,請點選https://blog.csdn.net/Aphysia/article/details/80291916

介面卡模式(百度百科):在計算機程式設計中,介面卡模式(有時候也稱包裝樣式或者包裝)將一個類的介面適配成使用者所期待的。一個適配允許通常因為介面不相容而不能在一起工作的類工作在一起,做法是將類自己的介面包裹在一個已存在的類中。

可以這麼理解,原來可能兩個介面或者兩個類不相容,介面卡模式要做的事情就是把它們統一管理,讓他們可以一起工作。舉個簡單的例子:記憶體卡和筆記本,是不能直接連線工作的,但是我們使用讀卡器,相當於介面卡,把它們連線起來了。

1.不使用介面卡的例子:
  •   需求:程式猿的工作是program(),教師的工作是teach(),那麼這些不同的職業,具體的工作都是不一樣的,這些程式猿program()方法內容也可能是不一樣的,比如說京東,阿里,騰訊等等,教師也是一樣的,不同學校的老師工作內容也各異。所以我們必須定義介面,不同工作內容的也可以通過實現自己的介面去實現。

    程式碼結果如下:

  IProgramer.class(程式猿擼程式碼的介面)

package com.noadapter;

public interface IProgramer {
    public void program();
}

  Programer.class(程式猿的類,實現了擼程式碼的介面)

package com.noadapter;

public class Programer implements  IProgramer {
    @Override
    public void program() {
        System.out.println("我是一個優秀的程式猿,我整天擼程式碼");
    }
}

  下面的教師介面以及實現教師的類也和上面程式猿的一樣:

ITeacher.class(教師教書介面):

package com.noadapter;

public interface ITeacher {
    public void teach();
}

  Teacher.class(實現了教書的教師類):


package com.noadapter;

public class Teacher implements ITeacher {
    @Override
    public void teach() {
        System.out.println("我是教師,我教育祖國的花朵");
    }
}

  MyTest.class 測試類:

package com.noadapter;

public class MyTest {
    public static void main(String []args){
        ITeacher teacher = new Teacher();
        IProgramer programer = new Programer();
        //必須挨個訪問他們的方法
        teacher.teach();
        programer.program();
    }
}

執行結果:

理解:如果不是用介面卡模糊,那麼我們要定義出所有的工種物件(程式猿,教師等等),還要為他們實現各自的介面,然後對他們的方法進行呼叫,這樣有多少個工種,就要寫多少個方法呼叫,比較麻煩。

2.只定義一個介面卡實現類

在前面的基礎上修改,增加了IWorkAdapter.class以及它的實現類WorkerAdapter.class,以及更改了測試方法,其他的都沒有改變,程式碼結構如下:

增加的IWorkAdapter.class(介面卡的介面):

public interface IWorkAdapter {
    //引數之所以是Object,是因為要相容所有的工種物件
    public void work(Object worker);
}

增加的WorkAdapter.class(介面卡的類):


public class WorkAdaper implements IWorkAdapter {
    @Override
    public void work(Object worker) {
        if(worker instanceof IProgramer){
            ((IProgramer) worker).program();
        }
        if(worker instanceof ITeacher){
            ((ITeacher) worker).teach();
        }
    }
}

更改過的測試類MyTest.class:

public class MyTest {
    public static void main(String []args){
        ITeacher teacher = new Teacher();
        IProgramer programer = new Programer();
        //把兩個工種放到物件陣列
        Object[] workers = {teacher,programer};
        //定義一個介面卡
        IWorkAdapter adapter = new WorkAdaper();
        //介面卡遍歷物件
        for(Object worker:workers){
            adapter.work(worker);
        }
    }
}

結果依然不變:

分析:只寫一個介面卡,功能上就像是把介面集中到一起,在中間加了一層,這一層把呼叫不同工種(程式猿,教師)之間的差異遮蔽掉了,這樣也達到了解耦合的作用。

3.多個介面卡的模式

也就是為每一個工種都定義一個介面卡(在一個介面卡的基礎上進行修改)

修改 IWorkAdapter.class

public interface IWorkAdapter {
    //引數之所以是Object,是因為要相容所有的工種物件
    public void work(Object worker);
    //判斷當前的介面卡是否支援指定的工種物件
    boolean supports(Object worker);
}

定義一個TeacherAdapter.class

public class TeacherAdapter implements IWorkAdapter{
    @Override
    public void work(Object worker) {
        ((ITeacher)worker).teach();
    }

    @Override
    public boolean supports(Object worker) {
        return (worker instanceof ITeacher);
    }
}

定義一個ProgrammerAdapter.class

public class ProgrammerAdapter implements IWorkAdapter{
    @Override
    public void work(Object worker) {
        ((IProgramer)worker).program();

    }
    @Override
    public boolean supports(Object worker) {
        return (worker instanceof IProgramer);
    }
}

測試類(Test.class):

public class MyTest {
    public static void main(String []args){
        ITeacher teacher = new Teacher();
        IProgramer programer = new Programer();
        //把兩個工種放到物件陣列
        Object[] workers = {teacher,programer};
        //介面卡遍歷物件
        for(Object worker:workers){
            IWorkAdapter adapter = getAdapter(worker);
            adapter.work(worker);
        }
    }
    public static IWorkAdapter getAdapter(Object object){
        IWorkAdapter teacherAdapter = new TeacherAdapter();
        IWorkAdapter programmerAdapter = new ProgrammerAdapter();
        IWorkAdapter[] adapters = {teacherAdapter,programmerAdapter};
        for(IWorkAdapter adapter:adapters){
            if(adapter.supports(object)){
                return adapter;
            }
        }
        return null;
    }
}

個人理解:其實多個介面卡的根本是去獲取支援該物件的介面卡,通過該介面卡來使用這個物件。

相關文章