My logo
Published on

adapter 适配器模式(重要)

1.适配器模式的原理与实现

适配器模式的英文翻译是 Adapter Design Pattern。顾名思义,这个模式就是用来做适配的。

它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类 可以一起工作。对于这个模式,

有一个经常被拿来解释它的例子,就是USB转接头充当适配器,把两种不兼容的接口,通过转接变得可以一起工作。

适配器模式有两种实现方式:类适配器和对象适配器。其中,类适配器使用继承关系来实现,对象适配器使用组合关系来实现。

2.在实际企业开发中的使用场景

这个模式一般是在系统不断升级的过程中使用,对已经写好的老的类,写一套适配器来适配老类,但是提供新的接口,

还有一种情况,是对于已有的第三方类库,比如redis的客户端,或者是elasticsearch的客户端,他们提供了一套API, 但是我们这里的要求是需要面向我们这里的DAO接口来进行编程,此时可以写一个适配器,将比如redis客户端的接口适配到我们的接口。

比如我们的DAO接口,要求的接口风格都是:saveupdateremovelistget,这些方法风格。

DAORedisImplredis客户端,getsetmsetmget,一套接口;适配器,DAORedisImpl就是一个适配器,这个适配器实现的是我们的DAO接口, 在我们的saveupdateremove等方法中,去调用redis客户端的getsetmsetmget等方法。

3.实际案例

比如:我们手头有有一套系统v1.0版本的老代码,现在要在这个基础之上构建v1.0的新代码。然后有了一个新的接口,需要让别人面向新接口开发,此时就只能开发适配器, 适配v1.0版本的类,但是实现的是v2.0的接口,别人调用v2.0的接口,内部却是基于v1.0的老类实现的功能。

场景介绍:

  1. 假设我们做了一个第一版的一个系统,这个系统里有一个接口和一个实现类
  2. 接着我们开始做第二版的系统,这个系统我们定义了一个新的接口,和新的实现类
  3. 但是我们同时在第二版的系统中,也要使用第一版系统中定义的那个老接口和老实现类
package wang.jinggo.basics.adapter;

/**
 * 不用设计模式的实现
 *
 * @author: wangyj
 * @create: 2021-10-18
 * @version: 1.0.0
 **/
public class WithoutAdapterPatternDemo {

    //老版本接口
    public static interface OldInterface {
        void oldExecute();
    }

    // 老版本接口的实现类
    public static class OldInterfaceImpl implements OldInterface {

        public void oldExecute() {
            System.out.println("老版本接口实现的功能逻辑");
        }
    }

    /**
     * 新版本接口
     */
    public static interface NewInterface {
        void newExecute();
    }

    public static class NewInterfaceImpl implements NewInterface {

        public void newExecute() {
            System.out.println("新版本接口实现的功能逻辑");
        }
    }

    public static void main(String[] args) {

        // 如果不用任何设计模式,我们的问题在哪儿?
        // 问题其实很明显,就是说,我们的新的代码中,融合了新老两套接口,很麻烦的一个事情
        // 首先如果你这么干的话,就会导致代码很恶心,面向的是规范和风格完全不同的两套接口,你理解和维护的成本提高了
        // 其次,假如说,现在都不给你选择使用老版本接口的机会
        // 直接强制性公司规范要求按照新版本接口来走,你的老版本接口的实现类,就没法用了啊?
        // 难不成还要基于新版本的接口重新写一套?
        OldInterface oldInterface = new OldInterfaceImpl();
        NewInterface newInterface = new NewInterfaceImpl();
        oldInterface.oldExecute();
        newInterface.newExecute();
    }
}

package wang.jinggo.basics.adapter;

/**
 * 适配器模式demo
 *
 * @author: wangyj
 * @create: 2021-10-18
 * @version: 1.0.0
 **/
public class AdapterPatterDemo {

    /**
     * 定义一个适配器类
     */
    public static class NewInterfaceAdapter implements NewInterface {

        private OldInterface oldInterface;

        public NewInterfaceAdapter(OldInterfaceImpl oldInterface) {
            this.oldInterface = oldInterface;
        }

        public void newExecute() {
            oldInterface.oldExecute();
        }
    }

    //老版本接口
    public static interface OldInterface {
        void oldExecute();
    }

    // 老版本接口的实现类
    public static class OldInterfaceImpl implements OldInterface {

        public void oldExecute() {
            System.out.println("老版本接口实现的功能逻辑");
        }
    }

    /**
     * 新版本接口
     */
    public static interface NewInterface {
        void newExecute();
    }

    public static class NewInterfaceImpl implements NewInterface {

        public void newExecute() {
            System.out.println("新版本接口实现的功能逻辑");
        }
    }

    public static void main(String[] args) {
        // 适配器模式
        // 就是你手上有新老俩接口和一个老接口的实现类
        // 但是现在系统中要面向新接口来开发,老接口的实现类就不能直接用了,不能直接面向老接口来开发
        // 开发一个老接口到新接口的一个适配器
        // 适配器是实现了新接口的,但是适配器中持有老接口实现类实例的引用
        // 适配器的新接口方法的实现,全部基于老接口实现类的老方法来实现即可
        // 对于调用方而言,只要使用适配器来开发即可,就可以通过面向新接口开发,底层使用老接口实现类
        NewInterface newInterface = new NewInterfaceAdapter(new OldInterfaceImpl());
        NewInterface newInterface1 = new NewInterfaceImpl();
        newInterface.newExecute();
        newInterface1.newExecute();
    }
}

4.总结

  • 封装有缺陷的接口设计
  • 统一多个类的接口设计
  • 替换依赖的外部系统
  • 兼容老版本接口
  • 适配不同格式的数据