Fork me on GitHub

适配器模式

定义

适配器模式的定义:将某个类的接口转换为接口客户所需类型,适配器模式解决的问题是:使得原本由于接口不兼容而不能一起工作、不能统一管理的那些类可以一起工作、可以进行同意管理。

举例实现

这里有教师接口ITeacher、程序员接口IProgrammer,分别用于定义他们各自工种的具体工作。然后定义深圳大学的教师SZUTeacher、腾讯的程序
员TcProgrammer。这些不同的工种所作的工作都各自不同,无法进行统一管理,协同工作。我们要做的是将这些不同工种的工作内容全部输出。

  • ITeacher接口

    1
    2
    3
    4
    5
    public interface ITeacher {

    void teach();

    }
  • IProgrammer接口

    1
    2
    3
    4
    5
    public interface IProgrammer {

    void code();

    }
  • SZUTeacher实现类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class SZUTeacher implements ITeacher {

    @Override

    public void teach() {

    System.out.println("教离散数学!");;

    }

    }
  • TcProgrammer实现类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class TcProgrammer implements IProgrammer {

    @Override

    public void code() {

    System.out.println("编php程序!");;

    }

    }
不使用适配器模式

不使用适配器模式,调用者需要定义出所有工作的对象,然后逐个对象调用自己的工作方法。


1
2
3
4
5
6
7
8
9
public class Test1 {
public static void main(String[] args) {
ITeacher teacher = new SZUTeacher();
IProgrammer programmer = new TcProgrammer();
//逐个对象调用自己的工作方法
teacher.teach();
programmer.code();
}
}

只定义一个适配器实现类

这种方式类似与多功能充电器,一个电源插头上接着多种类型的充电接口。用户使用充电器充电时,需要使用电器接口与多功能充电器的充电插口逐个对比,接口匹配则可以开始
充电。

  • 适配器接口

    1
    2
    3
    4
    5
    6
    7
    public interface IWorkerAdapter {

    //为了兼容所有工种员工,这里的参数必须是Object类型

    void work(Object worker);

    }
  • 单个适配器实现类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class WorkerAdapter implements IWorkerAdapter {

    @Override

    public void work(Object worker) {

    if(worker instanceof ITeacher){

    ((ITeacher) worker).teach();

    }

    if(worker instanceof IProgrammer){

    ((IProgrammer) worker).code();

    }

    }
    }
  • 调用者

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class Test2 {

    public static void main(String[] args) {

    ITeacher teacher = new SZUTeacher();

    IProgrammer programmer = new TcProgrammer();

    Object[] workers = {teacher, programmer};

    IWorkerAdapter workerAdapter = new WorkerAdapter();

    for(Object worker:workers){

    workerAdapter.work(worker);

    }

    }

    }
为每一个工种定义一个适配器

为每一个工种定义一个适配器

  • 适配器接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public interface IWorkerAdapter2 {

    void work(Object worker);

    //判断当前适配器是否支持指定工种对象

    boolean supprots(Object worker);

    }
  • Teacher适配器实现类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class TeacherAdapter implements IWorkerAdapter2 {

    @Override

    public void work(Object worker) {

    ((ITeacher)worker).teach();

    }

    @Override
    public boolean supprots(Object worker) {
    return (worker instanceof ITeacher);
    }
    }
  • Programmer适配器实现类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class ProgrammerAdapter implements IWorkerAdapter2 {

    @Override

    public void work(Object worker) {

    ((IProgrammer)worker).code();

    }

    @Override
    public boolean supprots(Object worker) {
    return (worker instanceof IProgrammer);
    }
    }
  • 调用者

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public class Test3 {

    public static void main(String[] args) {

    ITeacher teacher = new SZUTeacher();

    IProgrammer programmer = new TcProgrammer();

    Object[] workers = {teacher, programmer};

    for(Object worker:workers){

    IWorkerAdapter2 adapter = getAdapter(worker);

    adapter.work(worker);

    }

    }

    private static IWorkerAdapter2 getAdapter(Object worker) {
    IWorkerAdapter2 teacherAdapter = new TeacherAdapter();
    IWorkerAdapter2 programmerAdapter = new ProgrammerAdapter();
    //获取所有工种适配器
    IWorkerAdapter2[] allAdapter = {teacherAdapter, programmerAdapter};

    //遍历每一个适配器,尝试哪一个适配器是对应工种
    for(IWorkerAdapter2 adapter:allAdapter){
    if(adapter.supprots(worker)){
    return adapter;
    }
    }
    return null;
    }
    }
补充:缺省适配器模式
  • 缺省适配器模式是由适配器模式简化而来,省略了适配器模式中目标接口,也就是源接口和目标接口相同,原接口为接口,目标接口为类
  • 典型的缺省适配器模式是JavaEE规范中的Servlet接口与GenericServlet抽象类
  • Servlet接口中包含五个抽象方法,而其中的service()方法才是用于实现业务逻辑的、必须要实现的方法,另外四个方法一般都是空实现,或简单实现
    在这里插入图片描述

  • GenericServlet抽象类实现了Servlet接口的service()方法以外的另外四个方法,所以自定义的Servlet只需要继承GenericServlet抽象类,实现service()方法即可,无需再实现Servlet接口。

-------------本文结束感谢您的阅读-------------