zoukankan      html  css  js  c++  java
  • 适配器

    一、概述

    适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁,它结合了两个独立接口的功能,

    使得原本由于接口不兼容而不能一起工作的那些类可以一起工作,属于结构型模式。

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

    eg: 读卡器是作为内存卡和笔记本之间的适配器,

    内存卡  => 读卡器 => 笔记本

    将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

    分类:

       类适配器、对象适配器、接口适配器。

    角色模型:

      目标接口(Target):该角色把其他类转换为我们期望的接口

      被适配者/源接口(Adaptee):  原有的接口,也是希望被改变的接口

      适配器(Adapter):  将被适配者和目标接口组合到一起的类

     如上示例:选取笔记本为主体,笔记本需要读取内存卡,则笔记本为目标接口,内存卡为被适配者,读卡器为适配器。

    适配器模式结构图:

     

    二、使用

    1. 笔记本案例

    现有一个apple笔记本(USB接口),和一个内存卡(SM接口),如何实现apple读取内存卡数据?

    /**
     * 目标 Target
     */
    class Apple {
        public void usb() {
            System.out.println("数据从usb接口输入");
        }
    }
    
    /**
     * 源 Adaptee
     */
    interface Sm {
        void smType();
    }
    
    /**
     * 测试类*/
    public class AdapterTest {
        public static void main(String[] args) {
            // 原始的apple读取usb接口数据
            Apple apple = new Apple();
            AdapterTest.client(apple);
        }
    
        /**
         * 客户端
         */
        public static void client(Apple apple) {
            System.out.println("========苹果笔记本读取数据=======");
            apple.usb();
        }
    }

    当然,如上的源

    1.1 类适配器

    原理:通过继承特性来实现

    /**
     * 1.类适配器 Adapter
     */
    class ReaderCard extends Apple implements Sm {
        @Override
        public void smType() {
            System.out.println("数据从SM接口输出");
        }
    
        @Override
        public void usb() {
            this.smType();
            super.usb();
        }
    }
    
    public class AdapterTest {
        public static void main(String[] args) {       
            // 1.采用类适配器后,读取sm接口数据
            ReaderCard readerCard = new ReaderCard();
            AdapterTest.client(readerCard);
        }
    }

    总结:类适配器通过创建一个适配器类,使这个适配器继承Target和Adaptee接口,来将原来并不兼容的目标接口和源接口关联在了一起,这样使得适配器同时具有了两个接口的功能。客户端使用时,原来是要求传入一个Apple接口(后代),现在适配器也是Apple的后代,可以直接传递(面向接口编程)。

    1.2 对象适配器

    原理:通过组合方式 + 构造注入的方式实现

    /**
     * 2.对象适配器
     */
    class ReaderCard2 extends Apple {
        // 组合
        private Sm sm;
    
        // 构造注入
        public ReaderCard2(Sm sm) {
            this.sm = sm;
        }
    
        @Override
        public void usb() {
            sm.smType();
            super.usb();
        }
    }
    
    public class AdapterTest {
        public static void main(String[] args) {       
            // 2.对象适配器
            ReaderCard2 readerCard2 = new ReaderCard2(() -> System.out.println("数据从SM接口输出"));
            AdapterTest.client(readerCard2);
        }
    }

    总结:对象适配器通过创建一个适配器类,实现Target接口,然后使用构造注入的方式注入Adaptee,这样适配器类就组合了两个不兼容的接口,客户端要求使用Target接口,适配器又是Target的后代,这样就可以直接传递,同时,通过注入将源关联起来。

    1.3 类适配器

    原理:可以认为是和类适配器是同一种。

     2. 案例二

    都知道创建现在的第三种方式是通过实现Callable接口,那么它是如何和Thread关联上的?

    public class CallableDemo {
        public static void main(String[] args) throws Exception {
            // 两个线程,一个main线程,一个AAA futureTask
    
            // FutureTask(Callable<V> callable)
            FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread());new Thread(futureTask, "AAA").start();
        }
    }
    
    class MyThread implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {return 1024;
        }
    }
    
    class MyThread1 implements Runnable{
        @Override
        public void run() {
    
        }
    }

    创建线程需要传入一个Runnable接口,并没有构造方法让你去传Callable接口,而你有的只是一个Callable结构的实例,那你咋办?你如何将Callable传递给Thread呢?

    分析:接口支持多次实现,如果能找到一个类,这个类实现了Runnable接口,又实现了Callable接口,那么传递一个这样的类,即可解决问题,这就是适配器模式。

    (1) 创建线程需要传递Runnable接口,即只需要是Runnable的 后代接口、后台接口的实现类都可以传递,RunnableFuture接口实现了Runnable接口,类FutureTask又实现了RunnableFuture接口,所以可以传递FutureTask类;

    (2) FutureTask类的构造注入可以传递进去一个Callable接口,所以FutureTask可以整合Runnable和Callable接口;

     

      

    参考:

    适配器模式

    适配器模式的理解和示例

    Java设计模式之适配器模式

  • 相关阅读:
    获取农历日期
    图片上传代码(C#)
    ASP.net使用技术总结(1)GridView控件的单击处理
    JavaScript使用小技巧:IE8的关闭处理
    FrameSet左右收缩编码
    哈哈,开心!今天注册开通了 弟弟Kernel 的网志
    设计模式简介
    Delphi字符串、PChar与字符数组之间的转换
    C++中数组参数详解
    1、简单工厂模式
  • 原文地址:https://www.cnblogs.com/shiyun32/p/12591604.html
Copyright © 2011-2022 走看看