快速导航
一、适配器模式简介
二、代码展示
三、jdk中使用适配器模式的地方
四、用易懂的方式解释一下
一、适配器模式简介
定义: 将一个类的接口转换成客户期望的另一个接口,使原本接口不兼容的类可以一起工作.
适配器模式,实际生活中,就像把一个220v转为5v电源接口。
类型: 结构型
适用场景:
1、已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)
2、不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品,不同厂家造成功能类似而接口不相同的情况下的解决方案。
优点:
1、能提高类的透明性和复用,现有的类复用但不需要改变
2、目标类和适配器类解耦,提高程序扩展性
3、符合开闭原则
缺点:
1、适配器编写需要全面考虑,可能会增加系统的复杂性
2、增加系统代码可读的难度
扩展:
对象适配器:符合组合复用原则,使用委托机制。
类适配器:通过类继承来实现。
相关设计模式:
适配器模式和外观模式
适配器模式和装饰者模式
二、代码展示
适配器模式分为类适配器模式和对象适配器模式
先来演示类适配器模式:
/**
* @program: adpn-pattern->Adaptee
* @description: 被适配者
* @author: Jstar
* @create: 2019-11-26 21:16
**/
public class Adaptee {
public void adapteeTarget(){
System.out.println("被适配者的目标方法");
}
}
/**
* @program: adpn-pattern->Target
* @description: 目标接口
* @author: Jstar
* @create: 2019-11-27 09:09
**/
public interface Target {
public void getSomtehing();
}
/**
* @program: adpn-pattern->AbstractTarget
* @description: 实际目标类
* @author: Jstar
* @create: 2019-11-27 09:11
**/
public class AbstractTarget implements Target {
@Override
public void getSomtehing() {
System.out.println("AbstractTarget 实际的目标方法");
}
}
/**
* @program: adpn-pattern->Adapter
* @description: 适配器
* @author: Jstar
* @create: 2019-11-27 09:19
**/
public class Adapter extends Adaptee implements Target {
@Override
public void getSomtehing() {
super.adapteeTarget();
//然后可以做自己的业务处理
}
}
// 测试类
public class Test {
public static void main(String[] args) {
Target target=new AbstractTarget();
target.getSomtehing();
System.out.println("分割线====================");
Target adapterTarget=new Adapter();
adapterTarget.getSomtehing();
}
}
看一下,uml关系图:
上述代码中,适配器 Adapter 相当于把 Target 的方法移交给了 Adaptee 。达到一个适配模式。
运行结果:
演示一下对象适配器模式:
其实只是更改了 Adapter 类中 获取 Adaptee 的方式,两种最重要的区别是Adapter 和 Adaptee 是继承关系还是组合关系。
如下:
//对象类型 适配器
public class Adapter implements Target {
Adaptee adaptee=new Adaptee();
@Override
public void getSomtehing() {
adaptee.adapteeTarget();
//然后可以做自己的业务处理
}
}
uml类图:
运行结果和类适配器模式是一样的。
再来演示一个实际生活的例子以便于理解:
背景:假如我们想把220V交流电,转换为5V直流电,为手机充电,就需要一个适配器。
代码演示:
/**
* @program: adpn-pattern->AC220V
* @description: 220v交流电
* @author: Jstar
* @create: 2019-11-27 10:27
**/
public class AC220V {
public int outputAC(){
int outAC=220;
System.out.println("输出220v交流电");
return outAC;
}
}
/**
* @program: adpn-pattern->DC5V
* @description: 5v直流电
* @author: Jstar
* @create: 2019-11-27 10:29
**/
public interface DC5V {
public int output5V();
}
/**
* @program: adpn-pattern->A220vTo5vAdapter
* @description: 220V转5V适配器
* @author: Jstar
* @create: 2019-11-27 10:30
**/
public class A220vTo5vAdapter implements DC5V{
AC220V ac220V=new AC220V();
@Override
public int output5V() {
int outputAC = ac220V.outputAC();
int dc5v=outputAC/44;
System.out.println("电源适配器,输入:"+outputAC+"V,输出:"+dc5v+"V");
return dc5v;
}
}
/**
* @program: adpn-pattern->Test
* @description: 测试类
* @author: Jstar
* @create: 2019-11-27 10:36
**/
public class Test {
public static void main(String[] args) {
DC5V dc5V=new A220vTo5vAdapter();
int getpower=dc5V.output5V();
System.out.println("最终获取的电压为:"+getpower+"V");
}
}
以上为一个电源适配器模式,运行结果:
最终由 220v转为 5v,达到了预期结果。
三、jdk中的适配器模式
1、XmlAdapter 适配器
2、springmvc 的适配器 HandlerAdapter
HandlerAdapter主要有3个方法:
supports(),handle(),getLastModified()
supports()是判断该适配器是否支持这个HandlerMethod,就是当得到一个handler时,该接口子类该方法做判断(就是类似handler instanceof Controller的判断方式),用来得到适配这个handler的适配器子类。
handle()用来执行控制器处理函数,获取ModelAndView 。就是根据该适配器调用规则执行handler方法。
四、用易懂的方式解释(总结)一下
1、假如在系统的升级过程中,会有版本 v1.0,可能会升级为v2.0,在系统的升级过程中,接口的调用方需要用到v1.0老版本接口的逻辑,同时需要新增逻辑。
2、不用适配器的做法可能是,接口调用方 调用老接口,再新增新逻辑,完成功能。--但是这样做好吗?,有时候,我们规定,新版本接口调用方不要直接用老版本的接口,那这样只能是把老接口逻辑再实现一遍吗?,,这样工作量就大了,而且代码臃肿、复杂、重复。我们可以用适配器模式封装一下。
3、适配器模式新增接口,适配器接口调用老接口,使用老接口逻辑,再新增新逻辑,该适配接口为调用方提供服务。
4、这样调用方就和老接口解耦了,还不用重复写代码逻辑。