设计模式——适配器模式

适配器模式用于使不兼容的类能够协同工作,通过继承或组合实现。本文介绍了类适配器和对象适配器的实现方式,以及各自的优缺点。以手机充电为例,展示了如何使用适配器将220V电源转换为5V电源。此外,还讨论了接口适配器模式,提供默认实现以减少接口实现的压力。适配器模式在SpringMVC中的应用,如HandlerAdapter,展示了其在多态调用和扩展性上的优势。
摘要由CSDN通过智能技术生成

适配器模式(将不同类统一成一个类)

image-20220528131059017

适配器是让原来不能兼容的两个类可以兼容,可以交Adapter也可以叫Wrapper

实现原理:调用源接口的方法来实现新接口的功能

场景:手机充电

手机充电需要5V电源,而现在只有220V的电源。

解决方案是给电源添加一个适配器

类适配器(通过继承src来适配)(不推荐)

image-20220528132617167

实现:

手机(需要5V电压来充电)
public class Phone {
    void charging(Voltage5V v){
        if(v.getVoltage5V()==5){
            System.out.println("可以充电");
        }else{
            System.out.println("电压不满足要求");
        }
    }
}
220V电源
public class Voltage220V {
    public int getVoltage220V(){
        return 220;
    }
}
创建5V电源的接口
public interface Voltage5V {
    public int getVoltage5V();
}
适配器继承220V电源实现5V电源的功能
public class ClassAdapter extends Voltage220V implements Voltage5V{
    @Override
    public int getVoltage5V() {
        return getVoltage220V()/44;
    }
}
客户端
public class Client {
    public static void main(String[] args) {
        Phone phone=new Phone();
        phone.charging(new ClassAdapter());
    }
}

phone只知道传进来的是一个5V的电源,而不关心这个电源是从哪里来的,客户端通过传入适配器即可完成功能

优缺点

image-20220528135008975

缺点很明显,直接继承被适配的类是一种很不优雅的行为,因为java是单继承,迫使dst必须是一个接口,有一定的局限性。继承的好处是可以改写src中的方法来适配dst,灵活性更强。其他的适配器方法可以解决这些局限性。

对象适配器(将继承改成组合)(推荐)

根据合成复用原则,能使用组合的情况就不要使用继承,基于这个思想将上述的继承改成组合,这样dst也不再要求必须是接口,使用更加灵活

image-20220528171130216

只需要将适配器的继承改成组合即可,被适配的对象在构造函数中被传进来

public class ObjectAdapter implements Voltage5V {

    Voltage220V v;
    ObjectAdapter(Voltage220V v){
        this.v=v;
    }

    @Override
    public int getVoltage5V() {
        return v.getVoltage220V()/44;
    }
}

客户端:

public class Client {
    public static void main(String[] args) {
        Phone phone=new Phone();
        phone.charging(new ObjectAdapter(new Voltage220V()));
    }
}

接口适配器模式(可以不实现方法的接口)

接口适配器模式和上面两种的目的不同,接口适配器是给接口一个默认实现(比如空方法,抛出异常,或者一些简单的逻辑),这样创建对象或者继承这个适配器时,不用实现接口的所有方法,可以按照自己的需求实现自己想要的方法。

简而言之就是给接口一个默认实现,也可以在接口中使用default来达成相同的目的

interface Operators{
    void operator1();
    void operator2();
    void operator3();
}

abstract class OperatorAdapter implements Operators{

     @Override
     public void operator1() {
     }

     @Override
     public void operator2() {
     }

     @Override
     public void operator3() {
     }
 }

public interface InterfaceAdapterDemo {
    public static void main(String[] args) {
        OperatorAdapter operator = new OperatorAdapter() {
            @Override
            public void operator1() {
                System.out.println("使用方法1");
            }
        };
        operator.operator1();
    }
}

接口适配器,适用于不想实现接口所有的方式时使用

源码示例:SpringMVC的HandlerAdapter

image-20220528204214532

SpringMVC会根据URL进行最长前缀匹配原则拿到handler(也可以叫controller)

然后根据handler拿到能处理这个handler的Adapter,SpringMVC提供的Adapter有这些:

image-20220430192846168

遍历所有的Adapter,调用他们的support方法判断支不支持,来找到能处理的Adapter,我们自己写的Controller里的方法会由RequestMappingHandlerAdapter 来处理(处理带有@RequestMapping注解的方法)

然后会在DispatcherServlet调用Adapter的handle方法来执行目标方法。拿到的handler就是我们在controller中编写的业务逻辑,而想要执行这些业务逻辑需要我们配好好它需要的参数,以及处理好它的返回值,而完成这些工作的就是Adapter。

image-20220528210628243

适配器模式其实就是对src进行了包装,封装成一个同一的格式,使其能够被外部统一调用。比如SpringMVC的HandlerAdapter,各个Handler其实是毫不关联的,通过适配器进行包装,这样在DisPatcherServlet中就能够利用多态来同一调用,若后面有新的handler也只需要配置一个新的适配器即可完成功能扩展,十分方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值