设计模式之适配器模式

往期文章

  • springcloud整合knike4j聚合微服务接口文档
  • spring源码 - 条件注解@ConditionnalOnClass的原理分析
  • springboot项目实现导出pdf功能,这也太简单了吧

    文章目录

    • 往期文章
    • 一、介绍
    • 二、代码示例
      • 1. 新建两种类型的U盘
      • 2. 新建两种不同类型手机及其对应的实现类
      • 3. 运行示例
      • 4. 新建适配器类
    • 三、总结

一、介绍

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。

举个例子,现在市面上很多手机都是typeC的接口,但我们的U盘都是usb格式的接口,因此这两个接口是不兼容的,如果我们能在手机上使用usb的U盘,那将会方便很多。因此我们需要一个适配器,适配器的输入端插入U盘,输出端以TypeC的格式插到手机上,这样,手机就可以读取U盘中的文件了。

下面我们使用两种方式来解决这种接口不兼容的问题

  • 不使用设计模式
  • 使用适配器设计模式

二、代码示例

我们以手机和u盘为例,使用两种分别有USB接口和TypeC接口的手机,和两个分别为USB接口和TypeC接口的U盘,下面来看这两个手机如何使用这两个U盘。

1. 新建两种类型的U盘

  • usb类型的U盘

    public interface USB {
        
        public void work();
    }
    
    @Slf4j
    public class USBDisk implements USB {
    
        public USBDisk() {
            log.info("我是usb格式的U盘");
        }
        
        public void work() {
            log.info("usb格式的u盘正在提供数据服务");
        }
    }
    
    
  • typeC类型的U盘

    public interface TypeC {
    
        public void work();
    }
    
    @Slf4j
    public class TypeCDisk implements TypeC {
    
        public TypeCDisk() {
            log.info("我是typeC格式的U盘");
        }
        
        public void work() {
            log.info("typeC格式的u盘正在提供数据服务");
        }
    }
    
    

2. 新建两种不同类型手机及其对应的实现类

  • usb插槽的手机

    public interface USBPhone {
    
        public void work(USB usb);
    }
    
    @Slf4j
    public class USBVivo implements USBPhone {
    
        public USBVivo() {
            log.info("我是vivo手机,我只提供usb插槽");
        }
    
        @Override
        public void work(USB usb) {
            usb.work();
        }
    }
    
  • typeC插槽的手机

    public interface TypeCPhone {
    
        public void work(TypeC typeC);
    }
    
    @Slf4j
    public class TypeCHuaWei implements TypeCPhone {
    
        public TypeCHuaWei() {
            log.info("我是华为手机,我只提供typeC插槽");
        }
    
        public void work(TypeC typeC) {
            typeC.work();
        }
    }
    

3. 运行示例

在手机和U盘相互兼容的情况下,我们可以很简单的就把代码完成。

  • 提供usb插槽的vivo手机使用usb类型的U盘

    public class USBPhoneDemo {
    
        public static void main(String[] args) {
            // usb类型的U盘
            USBDisk disk = new USBDisk();
    
            // usb插槽的vivo手机
            USBPhone vivo = new USBVivo();
            // vivo从U盘读取数据
            vivo.work(disk);
        }
    }
    
  • 输出

    在这里插入图片描述

  • 提供typeC插槽的华为手机使用typeC类型的U盘

    public class TypeCPhoneDemo {
    
        public static void main(String[] args) {
            // typeC类型的U盘
            TypeC disk = new TypeCDisk();
    
            // usb插槽的华为手机
            TypeCPhone huaWei = new TypeCHuaWei();
            // 华为从U盘读取数据
            huaWei.work(disk);
        }
    }
    
  • 输出

    在这里插入图片描述

但是在手机插槽和U盘不兼容的情况下,手机是无法通过U盘读取数据的,这时我们需要适配器。

4. 新建适配器类

  • 新建将usb转为typeC的适配器类USB2TypeCAdapter

    因为该适配器输入USB类型的U盘,输出的是typeC的接口,所以本质上是一个TypeC类型的设备

    @Slf4j
    public class USB2TypeCAdapter implements TypeC {
    
        private final USB disk;
    
        public USB2TypeCAdapter(USB disk) {
            log.info("适配器正在适配usb类型的U盘与typeC插槽的手机...");
            this.disk = disk;
        }
    
        // 适配器工作时,其实是适配器内的usb在工作
        @Override
        public void work() {
            disk.work();
        }
    }
    
  • 适配器的应用

    typeC插槽的手机通过适配器读取usb类型的U盘

    public class Usb2TypeCDemo {
        
        public static void main(String[] args) {
    
            // usb形式的U盘
            USB usb = new USBDisk(); // 输出:我是usb格式的U盘
    
            // 但我的手机是typeC手机华为,因此我只能接收typeC类型的U盘
            TypeCPhone huawei = new TypeCHuaWei(); // 输出:我是华为手机,我只提供typeC插槽
    
            // 这时我搞一个usb适配器,这个适配器供typeC手机使用,适配器一头连接huawei, 一头连接U盘
            USB2TypeCAdapter usbUSB2TypeCAdapter = new USB2TypeCAdapter(usb); // 输出:适配器正在适配usb与typeC...
    
            // 华为从适配器中读取数据
            huawei.work(usbUSB2TypeCAdapter);    // 输出:usb接口的u盘正在提供数据服务
        }
    }
    
  • 输出

    设计模式之适配器模式_第1张图片

  • 新建将typeC转为usb的适配器类TypeC2USBAdapter

    因为该适配器输入typeC类型的U盘,输出的是usb的接口,所以本质上是一个usb类型的设备

    public class TypeC2USBAdapter implements USB {
    
        private final TypeC disk;
    
        public TypeC2USBAdapter(TypeC disk) {
            log.info("适配器正在适配usb类型的U盘与typeC插槽的手机...");
            this.disk = disk;
        }
    
        @Override
        public void work() {
            disk.work();
        }
    }
    
  • 适配器的应用

    usb插槽的手机通过适配器读取typeC类型的U盘

    public class TypeC2USBDemo {
    
        public static void main(String[] args) {
    
            // typeC形式的U盘
            TypeC typeC = new TypeCDisk(); // 输出:我是typeC格式的U盘
    
            // 但我的手机是usb手机vivo,因此我只能接收usb类型的U盘
            USBPhone vivo = new USBVivo(); // 输出:我是vivo手机,我只提供usb插槽
    
            // 这时我搞一个usb适配器,这个适配器供typeC手机使用,适配器一头连接huawei, 一头连接U盘
            TypeC2USBAdapter typeC2USBAdapter = new TypeC2USBAdapter(typeC); // 输出:适配器正在适配typeC类型的U盘与usb插槽的手机...
    
            // vivo从适配器中读取数据
            vivo.work(typeC2USBAdapter);    // 输出:typeC格式的u盘正在提供数据服务
        }
    }
    
  • 输出

    设计模式之适配器模式_第2张图片

三、总结

适配器模式本质上就是一个适配器类作为两个不兼容类的桥梁。



纸上得来终觉浅,绝知此事要躬行。

————————我是万万岁,我们下期再见————————

你可能感兴趣的:(设计模式,JAVA,设计模式,适配器模式,java)