介绍
看到适配器,想必大家都想到了给手机充电的充电器了吧,由于手机无法直接使用 220V 的电压对手机进行充电,需要用到充电器将 220V 电压转换为 5V 给手机进行充电。适配器模式的作用就是和手机充电器一样的,用来做接口的兼容的
适配器模式有两种实现方式,类适配器和对象适配器,类适配器使用的是继承的方式,而对象适配器使用的是组合的方式
下面通过交流转换的案例来更加深入的理解适配器模式
首先,家用的交流电是 220V,我们新建标准的交流电类,来为我们生活来供电
public class AC220{
private int output = 220;
public int useAC(){
System.out.println("输出" + output + "V交流电");
return output;
}
}
由于 220V 交流电无法直接给手机进行充电,因此我们需要对交流电进行变压,变压成 5V 才能给手机进行充电,因此创建适配器类,适配器的实现有两种方式,下面一一演示
类适配器
public class PhoneAdapter1 extends AC220{
@Override
public int useAC(){
int output = super.useAC();
output = output / 44;
System.out.println("交流电变压");
return output;
}
}
对象适配器
public class PhoneAdapter2 {
private AC220 ac220;
public PhoneAdapter2(AC220 ac220){
this.ac220 = ac220;
}
public int useAC(){
int output = ac220.useAC();
output = output / 44;
System.out.println("交流电变压");
return output;
}
}
这两种方式都是一样的,只是测试的时候有一点不同
最后进行测试
public class Demo{
public static void main(String[] args){
PhoneAdapter1 phoneAdapter1 = new PhoneAdapter1();
int ac1 = phoneAdapter1.useAC();
System.out.println("输出" + ac1 + "V交流电");
System.out.println("==========================");
PhoneAdapter2 phoneAdapter2 = new PhoneAdapter2(new AC220());
int ac2 = phoneAdapter2.useAC();
System.out.println("输出" + ac2 + "V交流电");
}
}
结果
输出220V交流电
交流电变压
输出5V交流电
==========================
输出220V交流电
交流电变压
输出5V交流电
适配器模式在 java 日志中的应用
使用 java 开发的日志框架有很多,例如 log4j、logback、jdk 提供的 JUL,Apache 提供的 JCL。这些日志框架都提供了相似的功能,都有不同的日志等级,INFO、WARN、ERROR、DEBUG 等,按照不同等级打印不同的日志,但是他们提供的接口不同,这就带来很多麻烦
在一个项目中可能要使用两个框架,比如 String 和 Mybatis,假设这两个框架使用的日志框架不同,这就需要我们在配置文件中分别配置这两种日志框架,比如日志打印格式,日志输出路径等,这就非常麻烦。
因此 Slf4j 出来了,他和 JDBC 一样,只提供了接口,没有提供实现,相当于给每一个日志框架定义了规范,每一个日志框架只要实现他所定义的接口,以后不管项目中引进了多少日志框架,都是用一套接口,也就没有了麻烦
然而,Slf4j 不像 JDBC 一样一开始就定义好了接口,它出现比 log4j、logback 等日志框架更晚,如果每个日志框架都重新实现这个接口,就会导致老项目编译出问题,都要全盘进行修改,这不符合开闭原则,这时候适配器模式就派上用场了,确实 Slf4j 也想到了这一点,给每个日志框架提供了适配器类,对每种日志框架进行二次封装,适配成 slf4j 接口的定义
所以,在开发业务系统,框架,组件的时候,我们统一使用 Slf4j 的接口来编写打印日志代码,具体使用哪种日志框架可以动态指定,利用 java 的 SPI 技术,只需将对应的依赖导入到项目中即可