Java学习 --- 设计模式的适配器模式

目录

一、适配器模式

二、适配器模式工作原理

 三、三种适配器模式的实现

3.1、类适配器模式

3.2、对象适配器模式

3.3、接口适配器模式

四、适配器模式在springMVC中的使用

 五、适配器的注意实现


一、适配器模式

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

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

3、主要有三种:类适配器模式、对象适配器模式、接口适配器模式。

二、适配器模式工作原理

1、将一个类的接口转换成另一个接口,让原本接口不兼容的类可以兼容

2、从用户的角度看不到被适配者,是解耦的。

3、用户调用适配器转化出来的目标接口方法,适配器再被适配者的相关接口方法。

4、用户收到反馈结果,只是觉得和目标结果交互。

 三、三种适配器模式的实现

3.1、类适配器模式

Adapter类通过继承src类,实现dst类接口,完成适配。

问题需求:220v的交流电需要是充电器适配给需要5v交流电的手机。

示例参考代码:

//被适配类
public class Voltage {
    public int output220(){
        int src = 220;
        return src;
    }
}
//适配接口
public interface IVoltage {
    public int output5();
}
public class VoltageAdapter extends Voltage implements IVoltage {

    @Override
    public int output5() {
        //获取220v
        int srcV = super.output220();
        int dstV = srcV / 44; //转换为5v电压
        return dstV;
    }
}
public class Phone {
    //充电
    public void charging(IVoltage iVoltage){
        int src = iVoltage.output5();
        if (src == 5){
            System.out.println("可以正常充电");
        }else {
            System.out.println("不可以正常充电");
        }
    }
}
public class Client {
    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter());
    }
}

代码分析:

1、Java是单继承机制,所以类适配器需要继承Voltage类是一个缺点,因为IVoltage必须是接口,有一定局限性。

2、Voltage类的方法会在VoltageAdapter类暴露出来,增加了使用成本。

3、因为继承了Voltage类,所以可以根据需要重写Voltage类的方法,使VoltageAdapter类更加灵活

3.2、对象适配器模式

1、将VoltageAdapter做修改,不再继承Voltage类,而是持有Voltage类,解决兼容性的问题。

2、根据“合成复用原则”,尽量使用关联关系替代继承关系。

3、对象适配器模式是适配器模式常用一种

示例参考代码:

其他代码不变,只需要修改这两个类:

public class VoltageAdapter  implements IVoltage {
    private Voltage voltage;
     //通过构造器传入Voltage实例
    public VoltageAdapter(Voltage voltage) {
        this.voltage = voltage;
    }

    @Override
    public int output5() {
       int dst = 0;
       if (voltage != null){
           int src = voltage.output220();
           dst = src / 44;
       }
       return dst;
    }
}
public class Client {
    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter(new Voltage()));
    }
}

代码分析:

1、对象适配器与类适配器思想相同,只是实现方式不同。根据合成复用原则,使用组合替代继承,解决了类适配器必须继承的局限性问题,不再要求IVoltage为接口。

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

3.3、接口适配器模式

1、当不需要全部实现接口提供的方法时,设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。

2、适合使用于一个接口不想使用其所有的方法的情况。

示例参考代码:

public interface Interface1 {
    public void m1();
    public void m2();
    public void m3();
}
//对Interface1的方法进行默认实现
public abstract class AbsAdepter implements Interface1 {
    @Override
    public void m1() {

    }
    @Override
    public void m2() {

    }
    @Override
    public void m3() {

    }
}
public class Client {
    public static void main(String[] args) {
     AbsAdepter absAdepter =  new AbsAdepter(){
            @Override
            public void m1() {
                super.m1();
                System.out.println("m1方法使用");
            }
        };
     absAdepter.m1();
    }
}

四、适配器模式在springMVC中的使用

1、springMVC中的HandlerAdapter中使用

 当请求过来时会在DispatcherServlet调用doDispatch方法

 mappedHandler相当于控制器,通过mappedHandler调用getHandler方法返回一个适配器

 在这里会返回一个适配器

 通过得到的适配器调用handle方法。

模拟springmvc通过适配器获取对应controller的源码

参考代码实现:

//多种Controller实现
public interface Controller {
}
class HttpController implements Controller{
    public void doHttpHandler(){
        System.out.println("http...");
    }
}
class SimpleController implements Controller{
    public void doSimplerHandler(){
        System.out.println("simple...");
    }
}
class AnnotationController implements Controller{
    public void doAnnotationHandler(){
        System.out.println("annotation...");
    }
}
//定义一个Adepter接口
public interface HandlerAdepter {
    public boolean supports(Object handler);
    public void handler(Object handler);
}
//多种适配器类
class SimpleHandlerAdepter implements HandlerAdepter{

    @Override
    public boolean supports(Object handler) {
        return (handler instanceof SimpleController);
    }

    @Override
    public void handler(Object handler) {
        ((SimpleController) handler).doSimplerHandler();
    }
}
class AnnotationHandlerAdepter implements HandlerAdepter{

    @Override
    public boolean supports(Object handler) {
        return (handler instanceof AnnotationController);
    }

    @Override
    public void handler(Object handler) {
        ((AnnotationController) handler).doAnnotationHandler();
    }
}
class HttpHandlerAdepter implements HandlerAdepter{

    @Override
    public boolean supports(Object handler) {
        return (handler instanceof HttpController);
    }

    @Override
    public void handler(Object handler) {
        ((HttpController) handler).doHttpHandler();
    }
}
public class DispatchServlet {
    public static void main(String[] args) {
        new DispatchServlet().doDispatch();
    }
    public static List<HandlerAdepter> handlerAdepters = new ArrayList<>();

    public DispatchServlet() {
        handlerAdepters.add(new AnnotationHandlerAdepter());
        handlerAdepters.add(new HttpHandlerAdepter());
        handlerAdepters.add(new SimpleHandlerAdepter());
    }
    public void doDispatch(){
        //模拟SpringMVC从request取handler的对象
        //适配器可以获取到希望的controller
        AnnotationController annotationController = new AnnotationController();
        //得到对应的适配器
        HandlerAdepter handler = getHandler(annotationController);
        //通过适配器执行对应的controller代码
        handler.handler(annotationController);
    }
    public HandlerAdepter getHandler(Controller controller){
        for (HandlerAdepter adepter: this.handlerAdepters) {
            if (adepter.supports(controller)){
                return adepter;
            }
        }
        return null;
    }
}

1、springMVC定义一个适配器接口,使得每一种Controller有一种对应的适配器实现类适配器代替controller执行相应的方法。

2、在扩展Controller时,只需要增加一个适配器类就完成了springMVC的扩展。

 五、适配器的注意实现

1、三种命名方式,是根据src是以怎样的形式给到Adapter来命令。

2、类适配器:以类给到,在Adapter里,就是将src当做类,继承。

      对象适配器:以对像给到,在Adapter里 ,将src作为一个对象,持有。

      接口适配器:以接口给到。在Adapter里,将src作为一个接口,实现。

3、Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸭鸭老板

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值