适配器模式详解

2020-02-11 15:21
1115
0
一、什么是适配器模式
      将一个系统的接口转换成另外一种形式,从而使原来不能直接调用的接口变得可以调用。适配器是作为两个不兼容的接口之间的桥梁属于结构型模式。
 
二、适配器模式角色划分
适配器模式涉及3个角色:
源(Adaptee):需要被适配的对象或类型, 旧版本或者苹果手机插口
适配器(Adapter):连接目标和源的中间对象,相当于插头转换器,新版本与老版本能够实现兼容
目标(Target):期待得到的目标, 新版本或者子头耳机
 
三、适配器模式应用场景
  1. 新老版本接口的兼容
  2. Mybatis种日志框架的整合
四、适配器创建的方式  
  对象适配器(组合模式)
  类适配器(继承模式)
  接口适配器模式(或又称作缺省适配器模式)
 
五、和代理模式、装饰器模式区别
装饰模式适合用于内部编写时,适配器适用于后期新增,不修改原有代码。
代理模式和装饰模式一般需要继承同一个抽象类,适配器可以不继承同一抽象类,也不一定需要在老方法前后做处理。
 
优点:
更好的复用性:系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。 
更好的扩展性:在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
缺点:
  过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
七、传统类图
八、代码示例
1、通过继承模式通过复写父类的方法,让本身适配看使用了哪些方法,适配器就继承父类,然后重写那些方法。这样可以与源对象进行替换,扩展了旧代码中方法入参支持的范围。
比如如下方式就让list适配了Map的功能:
public class ListAdapter extends HashMap {
    private List list;

    public ListAdapter(List list) {
        this.list = list;
    }

    @Override
    public int size() {
        return list.size();
    }
}
2、通过组合模式,要适配哪一个类就把其对象传入适配器中当做成员变量,这样能对功能进行适配,新增源对象的功能
如下源码实例,旧功能只能实现写入日志文件,新增需求写入日志文件后还要写入数据库,那么用适配器模式可以这样写:
public class LogAdapter implements LogWriteDbService {
    // 源 Adaptee
    private LogWriteFileService logWriteFileService;

    public LogAdapter(LogWriteFileService logWriteFileService) {
        this.logWriteFileService = logWriteFileService;
    }
    
    // 新增的扩展功能 既能够支持写入本地文件,也能支持写入数据库
    public void logWriteDb(LogBean logBean) {
        // 2.将数据写入到数据库中..
        System.out.println(">>>写入到数据库中..");
        //  写入本地文件
        logWriteFileService.logWriteFile();
    }
}

 

九、Mybatis日志模块对适配器模式应用

如下图所示,先找到mybatis的Log接口,看继承树发现mybatis对其他第三方日志框架都有其Log的实现类。

怎么让我本身的日志可以适配其他第三方日志呢,以log4j2为例,看如下Log4j2Impl代码可知,在构造函数中引用了log4j的类,生成了Logger对象,最后通过Log4j2LoggerImpl类和Log4j2AbstractLoggerImpl类转换成Mybatis自身的Log对象。

而具体的Log4j2LoggerImpl类中也很简单,如下就是把log4j2的日志对象通过构造函数传入,实现自己的Log接口,以log4j2的日志对象重写其方法。

Log4j2LoggerImpl和Log4j2Impl其实都是适配器,只是多了一层嵌套让外层的Log4j2Impl做了一些兼容判断。

 

参考文献:

https://www.runoob.com/design-pattern/adapter-pattern.html

http://www.mayikt.com/front/couinfo/194/0

全部评论