設計模式【6.2】– 再聊聊適配器模式

這裡說的適配器不是通常所說的類適配器,對象適配器,介面適配器,這裡實現的是把所有的類進行統一管理的適配器。如需要查找設計模式的三種主要適配器模式,請點擊//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;
    }
}

個人理解:其實多個適配器的根本是去獲取支援該對象的適配器,通過該適配器來使用這個對象。