适配器模式

  • 说到适配器模式相信大多数人肯定听过电源转换头的故事,这里我们再重复一遍:
    假如你到国外去,假如那个地方电源都是380v的,而你的手机充电器只能接220v的交流电,直接使用380v的会把手机充电器或者手机烧掉,那这时候怎么办呢?你需要准备一个380转220的电压转换器,其实就是变压器,把电源变成220v的就可以了;
    适配器的道理很简单,但是具体到java代码怎样实现呢?
    比如某公司做了一款公司内部使用的日志工具,可以把日志写入到文件保存,我们主要讨论设计模式,具体的写文件代码这里只使用控制台输出代替,第一版代码如下:

首先定义操作文件的接口

public interface LogToFile {
    void write(String log);
    void delete(String log);
    String read();
}

实现类:

public class LogToFileImpl implements LogToFile {
    @Override
    public void write(String log) {
        System.out.println("日志写到文件");
    }

    @Override
    public void delete(String log) {
        System.out.println("日志从文件删除");
    }

    @Override
    public String read() {
        System.out.println("从文件读取日志");
        return "";
    }
}

客户端使用

         LogToFile logToFile = new LogToFileImpl();
        logToFile.write("error");
        String read = logToFile.read();
        logToFile.delete("aaa");

这一版接口定义了读文件read、写文件write、从文件删除delete的方法

后来由于公司日志系统升级,新系统需要把日志保存到数据库中(我们只是举个例子生产中日志收集不是这么做的)
于是定义了新的交互接口api:实现数据库数据的crud

public interface LogToDb {
    void add(String log);
    void delete(String log);
    void update(String log);
    String query();
}

实现类:

public class LogToDbImpl implements LogToDb {
    @Override
    public void add(String log) {
        System.out.println("写到数据库");
    }

    @Override
    public void delete(String log) {
        System.out.println("从数据库删除");
    }

    @Override
    public void update(String log) {
        System.out.println("更新到数据库");
    }

    @Override
    public String query() {
        System.out.println("从数据库查询");
        return "";
    }
}

客户端使用:

//新版本写到数据库,并提供增删改查功能
        LogToDb logToDb = new LogToDbImpl();
        logToDb.add("aaa");
        logToDb.update("aaa");
        logToDb.delete("aaa");
        String query = logToDb.query();

好的,到这里为止我们有两套日志实现了,一个是file的一个是db的。
老系统使用file的没问题,新系统使用db的api也没问题,如果有用户目前并不希望升级log保存到数据库的版本,但是又想使用新版的提供了CRUD工能的接口去开发新功能(这样的好处是以后想升级db的实现,更换一个实现类就可以了不用改代码),如何实现呢?
者就用到了我们上面讲的适配器了,提供一个适配器类实现新的CRUD接口,但底层仍然用File版的实现类。可以顺便用上我们之前讲的简单工厂模式,封装LogToDb 接口,后期如果项目想用数据库保存日志,直接切换配置文件就好了

public class LogAdapter implements LogToDb {
    private LogToFile logToFile = new LogToFileImpl();

    @Override
    public void add(String log) {
        logToFile.write(log);
    }

    @Override
    public void delete(String log) {
        logToFile.delete(log);
    }

    @Override
    public void update(String log) {
        logToFile.delete(log);
        logToFile.write(log);
    }

    @Override
    public String query() {
        return logToFile.read();
    }
}

简单工厂:

public class LogFactory {
    LogToDb createLogger(){
        return new LogAdapter();
        //可以改为根据配置文件判断使用第一版File版本还是新的DB版本
        //return new LogToDbImpl();
    }
}

客户端使用,使用了简单工厂的代码是最后三行,上面的代码供参考

public static void main(String[] args) {
        //老版本,日志写到文件
        LogToFile logToFile = new LogToFileImpl();
        logToFile.write("error");
        String read = logToFile.read();
        logToFile.delete("aaa");
        //新版本写到数据库,并提供增删改查功能
        LogToDb logToDb = new LogToDbImpl();
        logToDb.add("aaa");
        logToDb.update("aaa");
        logToDb.delete("aaa");
        String query = logToDb.query();
        //不封装工厂直接使用适配器类
        LogAdapter adapter = new LogAdapter();
        adapter.add("调用的写到db的api方法,其实底层是写到文件");

        //封装工厂的使用方法
        LogToDb logger = LogFactory.createLogger();
        logger.add("a");
        String query1 = logger.query();
    }
  • 双向适配器
    上面的例子是我们可以通过新接口api但是底层仍然使用老的实现,当然也可以使用老的api底层使用新的实现,这种两种都兼容的适配器就叫做双向适配器,简单来说就是适配器类同时实现新老两个接口,注入新老两个实现类,不同的接口方法就交给相应的实现类完成。

我们上面举的例子是新老接口的兼容。
适配器模式的有点可以解决接口的兼容问题,但是相应的过多的使用和滥用适配器模式会让系统变得非常凌乱,一般的原则是能不用就不用。
适配器模式本质:转换匹配,复用功能

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值