美文网首页Java
设计模式之适配器模式

设计模式之适配器模式

作者: Vchar_Fred | 来源:发表于2020-08-08 16:58 被阅读0次

    概述

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

    适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)

    这种模式涉及到一个单一的类,该类负责加入独立或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

    主要分为三类:类适配器模式、对象的适配器模式、接口的适配器模式

    适配器的流程类似如下:需要被适配的->Adapter->最终想要的

    特点:

    1、可以让任何两个没有关联的类一起运行。

    2、提高了类的复用。

    3、增加了类的透明度。

    4、灵活性好。

    注意:适配器不是在详细设计时添加的,主要是解决正在服役的项目的问题。

    使用场景

    1. 系统需要使用现有的类,而这些类的接口不符合系统的需要。
    2. 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
    3. 需要一个统一的输出接口,而输入端的类型不可预知。

    在实际使用中无需过于拘泥于以下设计模式的例子,可根据实际业务需要进行设计。

    电压类适配器示例

    场景:充电器例子,需要将220v的电压转换为5v的电压。

    需要被适配已有220v电压的类

    /**
     * 需要适配已有220v电压的类
     */
    static class Voltage220 {
    
        public int output220V(){
            System.out.println("输出220v电压");
            return 220;
        }
    }
    

    需要的5v的接口

    /**
     * 需要的5v的接口
     */
    interface Voltage5 {
        /**
         * 需要输出5v电压
         */
        int output5V();
    }
    

    电压适配器

    /**
     * 适配器
     */
    static class VoltageAdapter extends Voltage220 implements Voltage5 {
    
        @Override
        public int output5V() {
            // 将输入5v的参数转为220v的获取执行结果
            int voltage = output220V();
            // 将结果转换为5v需要的返回结果
            System.out.println("适配器开始工作,转换电压为5v");
            return voltage/44;
        }
    }
    

    使用

    public static void main(String[] args) {
        // 创建Voltage5时使用适配器来创建
        Voltage5 voltage5 = new VoltageAdapter();
        int voltage = voltage5.output5V();
        if (voltage==5){
            System.out.println("电压适配成功,开始充电");
        }else {
            System.out.println("电压适配失败,充电器即将爆炸,请马上断开电源");
        }
    }
    

    类适配器,让Adapter继承需要被适配的的类,在里面对其进行处理;由于Java的单继承机制,其使用成本也增加了;

    对象适配器

    /**
     * 需要的5v的接口
     */
    interface Voltage5 {
        /**
         * 需要输出5v电压
         */
        int output5V();
    }
    
    /**
     * 需要适配已有220v电压的类
     */
    static class Voltage220 {
    
        public int output220V(){
            System.out.println("输出220v电压");
            return 220;
        }
    }
    
    static class VoltageAdapter implements Voltage5 {
    
        private Voltage220 voltage220;
        // 让适配器持有需要适配的对象
        public VoltageAdapter(Voltage220 voltage220){
            this.voltage220 = voltage220;
        }
    
        @Override
        public int output5V() {
            int voltage = voltage220.output220V();
            System.out.println("适配器开始工作,转换电压为5v");
            return voltage/44;
        }
    }
    

    使用

    public static void main(String[] args) {
        VoltageAdapter voltageAdapter = new VoltageAdapter(new Voltage220());
        int voltage = voltageAdapter.output5V();
        if (voltage==5){
            System.out.println("电压适配成功,开始充电");
        }else {
            System.out.println("电压适配失败,充电器即将爆炸,请马上断开电源");
        }
    }
    

    将对象传递给适配器

    接口适配器

    interface WxPay {
    
        void pay();
    
        void refund();
    
    }
    
    static abstract class WxPayAdapter implements WxPay {
        @Override
        public void pay(){
    
        }
    
        @Override
        public void refund(){
    
        }
    }
    

    使用

    public static void main(String[] args) {
    
        WxPay wxPay = new WxPay() {
            @Override
            public void pay() {
                System.out.println("支付实现");
            }
    
            @Override
            public void refund() {
                System.out.println("退款实现");
            }
        };
        wxPay.pay();
    
        // 使用适配器后只需要实现我们需要的即可
        WxPayAdapter wxPayAdapter = new WxPayAdapter() {
            @Override
            public void pay() {
                System.out.println("支付实现");
            }
        };
        wxPayAdapter.pay();
    }
    

    以接口为目标的适配器;这种方式在安卓中非常常见,比如添加相关的监听器,我只需要实现我们需要的即可,对应不需要的无需去实现,简化了代码。

    接口升级兼容示例

    未使用设计模式时

    public class NoAdapterPattern {
    
        public static void main(String[] args) {
            MediaPlayerV1 oldObject = new MediaPlayerV1Impl();
            MediaPlayerV2 newObject = new MediaPlayerV2Impl();
            oldObject.play();
            newObject.play();
        }
    
        /**
        * v1版本接口
        */
        public static interface MediaPlayerV1 {
    
            void play();
        }
    
        /**
        * v1版本接口实现类
        */
        public static class MediaPlayerV1Impl implements MediaPlayerV1 {
    
            @Override
            public void play() {
                System.out.println("播放mp3");
            }
        }
    
        /**
        * v2版本接口
        */
        public static interface MediaPlayerV2 {
    
            void play();
        }
    
        /**
        * v2版本接口实现类
        *
        */
        public static class MediaPlayerV2Impl implements MediaPlayerV2 {
            @Override
            public void play() {
                System.out.println("播放mp4");
            }
        }
    }
    

    使用类适配器模式

    public class AdapterPatter {
    
        public static void main(String[] args) {
            // 将v1版本的转换为v2版本的接口
            MediaPlayerV2 oldObject = new NewInterfaceAdapter();
            MediaPlayerV2 newObject = new MediaPlayerV2Impl();
            oldObject.play();
            newObject.play();
        }
    
        /**
        * 定义一个适配器类
        */
        public static class NewInterfaceAdapter implements MediaPlayerV2 {
    
            private final MediaPlayerV1 v1;
    
            public NewInterfaceAdapter(){
                this.v1 = new MediaPlayerV1Impl();
            }
    
            @Override
            public void play() {
                // 实际调用v1版本的实现
                this.v1.play();
            }
        }
    
    
        /**
        * v1版本接口
        */
        public static interface MediaPlayerV1 {
    
            void play();
        }
    
        /**
        * v1版本接口实现类
        */
        public static class MediaPlayerV1Impl implements MediaPlayerV1 {
    
            @Override
            public void play() {
                System.out.println("播放mp3");
            }
        }
    
        /**
        * v2版本接口
        */
        public static interface MediaPlayerV2 {
    
            void play();
        }
    
        /**
        * v2版本接口实现类
        */
        public static class MediaPlayerV2Impl implements MediaPlayerV2 {
            @Override
            public void play() {
                System.out.println("播放mp4");
            }
        }
    }
    

    适配器的新接口方法的实现,全部基于老接口实现类的老方法来实现即可;对于调用方,只要使用适配器来开发即可,就可以通过面向新接口开发,底层使用老接口实现类。

    相关文章

      网友评论

        本文标题:设计模式之适配器模式

        本文链接:https://www.haomeiwen.com/subject/zemhdktx.html