23种设计模式(9)——适配器模式

目录

一、基本介绍

二、demo

2.1、类适配器模式

类适配器模式注意事项和细节

2.2、对象适配器模式

对象适配器模式注意事项和细节

2.3、接口适配器模式

 接口适配器模式介绍

三、适配器模式在框架中的应用

3.1在 SpringMVC 框架应用

3.2、spring AOP中的适配器模式


一、基本介绍

1) 适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)

2) 适配器模式属于结构型模式

3) 主要分为三类:类适配器模式、对象适配器模式、接口适配器模式

二、demo

2.1、类适配器模式

以生活中充电器的例子来讲解适配器,充电器本身相当于 Adapter,220V 交流电相当于 src (即被适配者),我们的目 dst(即 目标)是 5V 直流电。

package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:45
 * @Des: 被适配者
 */
public class Voltage220V {

    public int output220V() {
        int src = 220;
        System.out.println("电压:" + src);
        return src;
    }
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:46
 * @Des: 目标
 */
public interface IVoltage5V {
    int output5V();
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:46
 * @Des: 适配器
 */
public class VoltageAdapter extends Voltage220V implements IVoltage5V{
    @Override
    public int output5V() {
        int srcV = output220V();
        int dstV = srcV / 44;
        return dstV;
    }
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:47
 * @Des: 使用者
 */
public class Phone {
    public void charging(IVoltage5V iVoltage5V) {
        if (iVoltage5V.output5V() == 5) {
            System.out.println("电压为5伏可以充电!");
        } else if (iVoltage5V.output5V() > 5) {
            System.out.println("电压不符!无法充电!");
        }
    }
}

测试:

package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:46
 * @Des:
 */
public class Test {
    public static void main(String[] args) {
        System.out.println("适配器模式");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter());
    }
}

类适配器模式注意事项和细节

1) Java 是单继承机制,所以类适配器需要继承 src 类这一点算是一个缺点, 因为这要求 dst 必须是接口,有一定局限性;

2) src 类的方法在 Adapter 中都会暴露出来,也增加了使用的成本。

由于其继承了 src 类,所以它可以根据需求重写 src 类的方法,使得 Adapter 的灵活性增强了。

2.2、对象适配器模式

继续以生活中充电器的例子来讲解,充电器本身相当于 Adapter,220V 交流电相当于 src (即被适配者),我们的目 dst(即目标)是 5V 直流电,使用对象适配器模式完成。

package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:57
 * @Des:
 */
public class VoltageAdapter2Object implements IVoltage5V {
    private Voltage220V voltage220V;

    public VoltageAdapter2Object(Voltage220V voltage220V) {
        this.voltage220V = voltage220V;
    }

    @Override
    public int output5V() {
        int dstV = 0;
        if (voltage220V != null) {
            int srcV = voltage220V.output220V();
            dstV = srcV / 44;
        }
        return dstV;
    }
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:46
 * @Des:
 */
public class Test {
    public static void main(String[] args) {
        System.out.println("适配器模式");
        Phone phone = new Phone();
        //phone.charging(new VoltageAdapter());

        phone.charging(new VoltageAdapter2Object(new Voltage220V()));
    }
}

对象适配器模式注意事项和细节

1) 对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。

根据合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承 src 的局限性问题,也不再要求 dst必须是接口。

2) 使用成本更低,更灵活。

2.3、接口适配器模式

 接口适配器模式介绍

核心思路:当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求, 适用于一个接口不想使用其所有的方法的情况。

package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 15:03
 * @Des:
 */
public interface InterfaceTest {
    void method1();
    void method2();
    void method3();
    void method4();
    void method5();
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 15:04
 * @Des:
 */
public class AbstractAdapter implements InterfaceTest {
    @Override
    public void method1() {
    }

    @Override
    public void method2() {
    }

    @Override
    public void method3() {
    }

    @Override
    public void method4() {
    }

    @Override
    public void method5() {
    }

    public static void main(String[] args) {
        new AbstractAdapter() {
            @Override
            public void method1() {
                // TODO Auto-generated method stub
                super.method1();
            }
        };
    }
}

三、适配器模式在框架中的应用

3.1在 SpringMVC 框架应用

1) SpringMvc 中的 HandlerAdapter就使用了适配器模式

2) SpringMVC 处理请求的流程回顾:

DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由HandlerAdapter 适配器处理。HandlerAdapter 作为期望接口,具体的适配器实现类用于对目标类进行适配,Controller 作为需要适配的类。

为什么要在 Spring MVC 中使用适配器模式? Spring MVC 中的 Controller 种类众多,不同类型的 Controller 通过不同的方法来对请求进行处理。如果不利用适配器模式的话,DispatcherServlet 直接获取对应类型的 Controller,需要 if else 来进行判断是哪一种子类然后执行。

3.2、spring AOP中的适配器模式

我们知道 Spring AOP 的实现是基于代理模式,但是 Spring AOP 的增强或通知(Advice)使用到了适配器模式,与之相关的接口是AdvisorAdapter 。Advice 常用的类型有:BeforeAdvice(目标方法调用前,前置通知)、AfterAdvice(目标方法调用后,后置通知)、AfterReturningAdvice(目标方法执行结束后,return之前)等等。每个类型Advice(通知)都有对应的拦截器:MethodBeforeAdviceInterceptor、AfterReturningAdviceAdapter、AfterReturningAdviceInterceptor。Spring预定义的通知要通过对应的适配器,适配成 MethodInterceptor接口(方法拦截器)类型的对象(如:MethodBeforeAdviceInterceptor 负责适配 MethodBeforeAdvice)。

猜你喜欢

转载自blog.csdn.net/cj_eryue/article/details/130266365