适配器模式详解与应用
作者:鱼仔
博客首页: https://codeease.top
公众号:Java鱼仔
# (一)什么是适配器模式
引用一个最经典的例子,我们自己家里的电压都是220V的,而早期的手机充电时所用的都是5V的电压。要想让手机在220V的家庭电压下充电,就需要一个电源适配器。在编程中,也经常会出现一个类程序无法直接去使用,而需要通过适当变换的行为抽象出来的设计模式就是适配器模式。
百度百科对适配器模式的介绍如下:在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
# (二)适配器模式中的角色
适配器中的角色主要有三种:
1、目标角色:目标角色指的是需要通过适配器后实现某些功能的角色,也就是上面这个例子中的5V电压。
2、适配器角色:适配器角色是适配器模式的主人公,目标角色和源角色之间的桥梁,也就是上面这个例子中的电源适配器,将220V的电压转化为5V。
3、源角色:源角色指的是原始的角色,也就是上面这个例子中的220V电压。
# (三)适配器模式的两种实现
# 3.1 类适配模式
类适配模式通过类的继承来实现适配器模式,接下来我会通过代码来展示开头的这个适配器例子。
首先我们来理清这个例子中的三个角色:
源角色:220V的电压
public class E220V {
public int get220V(){
return 220;
}
}
2
3
4
5
目标角色:5V电压
public interface E5V {
public int get5V();
}
2
3
适配器:220V转5V电压
public class EAdapter extends E220V implements E5V{
@Override
public int get5V() {
int sourceResult = super.get220V();
return sourceResult/44;
}
}
2
3
4
5
6
7
使用适配器:
public static void main(String[] args) {
E5V e5V = new EAdapter();
System.out.println(e5V.get5V());
}
2
3
4
# 3.2 对象适配模式
对象适配模式用通俗的话来讲就是将方法的实现委托给其他人来执行。
源角色和目标角色和之前的保持一致:
源角色:220V的电压
public class E220V {
public int get220V(){
return 220;
}
}
2
3
4
5
目标角色:5V电压
public interface E5V {
public int get5V();
}
2
3
适配器:220V转5V电压
public class EAdapter implements E5V{
private E220V e220V;
EAdapter(E220V e220V){
this.e220V=e220V;
}
@Override
public int get5V() {
int sourceResult = e220V.get220V();
return sourceResult/44;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
和类适配模式的区别在于,类适配模式通过继承的方式拿到了源角色的方法,而对象是直接引入了源角色,再使用源角色的方法。
# (四)适配器模式使用的时机
我的主管和我说过这样一句话,写代码最快的方法就是直接写,不考虑任何的模式。但是这样写代码会导致冗余代码越来越多,代码越来越难维护。使用设计模式或者使用某些架构方式可能会让写代码花更多时间,但是能给程序带来更强大的扩展能力和可维护能力。
适配器模式的第一个使用时机是对已有的类的重复使用:就比如我们写了一个220V的类,并且已经通过了大量测试和使用,这个类已经很稳定了,我们就可以在这个类的基础上使用适配器模式开发新的类。
第二个使用时机是当新的需求需要修改原有代码时:有的时候我们已经写好了一个需求已经上线,这个时候产品或者客户又提了一个新的小需求,可能在原有代码上修改很快就能解决,但是很有可能导致和原有其他功能的不兼容,这个时候就可以使用适配器模式。
第三个应用场景是版本的迭代兼容:软件在它的生命周期中会不断的升级,这就难免会出现新版本无法兼容老版本的情况,这种时候就可以使用适配器来同时兼容新老版本。后续我会通过一个JDK的实例展示这个场景。
# (五)适配器模式在框架中的应用
1、适配器模式最经典的使用案例就是JDK1.0时用于遍历容器的Enumeration接口,在JDK1.2时使用iterator来代替,为了兼容1.0时期的Enumeration,Collections类中使用适配器模式,兼容新老版本。这里用的是对象适配模式,用iterator代替Enumeration。
2、Spring框架中DispatcherServlet类的doDispatch方法中也能看到适配器模式的身影,它的作用是传递request的Controller并执行相应的方法、返回ModeView对象。Spring定义了适配接口,每个Controller有自己对应的适配器实现类,从而避免了大量if/else代码。
# (六)总结
本篇文章介绍了适配器模式的基本原理、基本使用以及框架中的实现,想要在真实项目中使用还是需要不断练习。