菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
110
0

适配器模式

原创
05/13 14:22
阅读数 67701

第一、适配器模式定义

适配器指的的是将一个系统的接口转换为另外一种形式,由原来的不能直接调用的接口变得可以调用。

适配器适用于以下几种业务场景:
1、已经存在的类,它的方法和需求不匹配(方法结果相同或相似)的情况。
2、适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案。有点亡羊补牢的感觉。
生活中也非常的应用场景,例如电源插转换头、手机充电转换头、显示器转接头。
3、新老版本的接口的兼容
4、Mybatis多种日志框架的整合

第二、适配器的角色划分

适配器模式涉及3个角色:

源(Adaptee):需要被适配的对象或类型, 旧版本或者苹果手机插口

适配器(Adapter):连接目标和源的中间对象,相当于插头转换器,新版本与老版本能够实现兼容

目标(Target):期待得到的目标, 新版本或者圆子头耳机

适配器模式包括3种形式:类适配器模式、对象适配器模式、接口适配器模式(或又称作缺省适配器模式)。

第三、适配器快速入门案例

比如早期的时候V1版本订单接口的入参为Map类型,随着业务的更新和迭代在V2版本的时候该订单接口的入参需要支持List的类型? 请问不改变的该接口代码的情况下,如何实现支持List类型。

/**
 * 实现类
 */
public class ListEx {
    public static void froOrderMap(Map map) {
        for (int i = 0; i < map.size(); i++) {
            // 使用I作为MapKey获取数据
            Integer value = Integer.valueOf(map.get(i).toString());
            System.out.println("value:" + value);
        }
    }
}
/**
 * list适配器
 */
public class ListAdapter extends HashMap {
    private List<Integer> list;

    public ListAdapter(List<Integer> list){
        this.list = list;
    }
    @Override
    public Object get(Object key) {
        return list.get(Integer.valueOf(key.toString()));
    }

    @Override
    public int size() {
        return list.size();
    }
    public void add(Object key){
        list.add(Integer.valueOf(key.toString()));
    }
}
/**
 * 测试类
 */
public class Test001 {
    public static void main(String[] args) {
        ListAdapter list = new ListAdapter(new ArrayList<Integer>());
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        ListEx.froOrderMap(list);
    }
}

 第四、使用适配器模式实现日志收集

比如设计一个日志收集系统,可能会考虑文件写入、也可能考虑写入MQ、也可能考虑写入数据库等。

/**
 * 写入文件
 */
public interface LogWriteFileService {

    public void writerFile();
}
/*
实现类
*/
public class LogWriteFileServiceImpl implements LogWriteFileService {
    @Override
    public void writerFile() {
        System.out.println("写入文件");
    }
}
/**
 * 写入数据库
 */
public interface LogWriterDBService {

    public void writerDB();
}
/**
 * 适配器
 */
public class LogAdapter extends LogWriteFileServiceImpl implements LogWriterDBService {
    @Override
    public void writerDB() {
        System.out.println("将数据写入数据库");
        //将数据写入文件
        this.writerFile();
    }
}
/**
 * 测试类
 */
public class Test002 {

    public static void main(String[] args) {
        LogAdapter logAdapter = new LogAdapter();
        logAdapter.writerDB();
    }
}

 第五、适配器的优缺点

优点:
1、能提高类的透明性和复用,现有的类复用但不需要改变。
2、目标类和适配器类解耦,提高程序的扩展性。
3、在很多业务场景中符合开闭原则。
缺点:
1、适配器编写过程需要全面考虑,可能会增加系统的复杂性。
2、增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。

第六、mybatis日志收集

Java开发中经常用到的日志框架有很多,Log4j、Log4j2、slf4j等等,Mybatis定义了一套统一的日志接口供上层使用,并为上述常用的日志框架提供了相应的适配器

在Mybatis的日志模块中就是使用了适配器模式。Mybatis内部在使用日志模块时,使用了其内部接口 org.apache.ibatis.logging.Log,但是常用的日志框架的对外接口各不相同,Mybatis为了复用和集成这些第三方日志组件,在其日志模块中,提供了多种Adapter,将这些第三方日志组件对外接口适配成org.apache.ibatis.logging.Log,这样Myabtis 就可以通过Log接口调用第三方日志了

源码分析

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

发表评论

0/200
110 点赞
0 评论
收藏
为你推荐 换一批