zoukankan      html  css  js  c++  java
  • 适配器设计模式

    一 概述
    定义:适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)。适配器模式主要是用来参数转化的。
    属于结构型模式,主要分为三类:类适配器模式、对象的适配器模式、接口的适配器模式

    本文定义:
    需要被适配的类、接口、对象(我们有的),简称 src(source);最终需要的输出(我们想要的),简称 dst (destination,即Target);适配器称之为 Adapter 。
    一句话描述适配器模式的感觉: src->Adapter->dst,即src以某种形式(三种形式分别对应三种适配器模式)给到Adapter里,最终转化成了dst。
    拿我们Android开发最熟悉的展示列表数据的三大控件:ListView,GridView,RecyclerView的Adapter来说,它们三个控件需要的是View(dst),而我们有的一般是datas(src),所以适配器Adapter就是完成了数据源datas转化成ItemView的工作。
    带入src->Adapter->dst中,即datas->Adapter->View.

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

    二 类适配器模式:
    一句话描述:Adapter类,通过继承 src类,实现 dst 类接口,完成src->dst的适配。
    别的文章都用生活中充电器的例子来讲解适配器:充电器本身相当于Adapter,220V交流电相当于src,我们的目dst标是5V直流电。我们现有的src类:

     1 /**
     2  * @Author: guodong
     3  * @Date: 2021/3/1 15:13
     4  * @Version: 1.0
     5  * @Description:
     6  */
     7 public class Voltage220 {
     8 
     9     public int output220V() {
    10         int src = 220;
    11         System.out.println("我是" + src + "V");
    12         return src;
    13     }
    14 }

    我们想要的dst接口:

     1 /**
     2  * @Author: guodong
     3  * @Date: 2021/3/1 15:14
     4  * @Version: 1.0
     5  * @Description:
     6  */
     7 public interface Voltage5 {
     8     
     9     int output5V();
    10     
    11 }

    适配器类:

     1 /**
     2  * @Author: guodong
     3  * @Date: 2021/3/1 15:15
     4  * @Version: 1.0
     5  * @Description:
     6  */
     7 public class VoltageAdapter extends Voltage220 implements Voltage5 {
     8     @Override
     9     public int output5V() {
    10         int src = output220V();
    11         System.out.println("适配器工作开始适配电压");
    12         int dst = src / 44;
    13         System.out.println("适配完成后输出电压:" + dst);
    14         return dst;
    15     }
    16 }

    Client类:

     1 public class Mobile {
     2     /**
     3      * 充电方法
     4      *
     5      * @param voltage5
     6      */
     7     public void charging(Voltage5 voltage5) {
     8         if (voltage5.output5V() == 5) {
     9             System.out.println("电压刚刚好5V,开始充电");
    10         } else if (voltage5.output5V() > 5) {
    11             System.out.println("电压超过5V,都闪开 我要变成note7了");
    12         }
    13     }
    14     
    15 }

    测试代码:

        public static void main(String[] args) {
            System.out.println("===============类适配器==============");
            Mobile mobile = new Mobile();
            mobile.charging(new VoltageAdapter());
        }

    输出:

    ===============类适配器==============
    我是220V
    适配器工作开始适配电压
    适配完成后输出电压:5
    电压刚刚好5V,开始充电

    类图如下:

    小结:
    Java这种单继承的机制,所有需要继承的我个人都不太喜欢。所以类适配器需要继承src类这一点算是一个缺点,因为这要求dst必须是接口,有一定局限性;且src类的方法在Adapter中都会暴露出来,也增加了使用的成本。但同样由于其继承了src类,所以它可以根据需求重写src类的方法,使得Adapter的灵活性增强了。(被适配的类是接口,适配器要实现接口,继承源类,有一定的局限性)

    三 对象适配器模式(常用):
    基本思路和类的适配器模式相同,只是将Adapter类作修改,这次不继承src类,而是持有src类的实例,以解决兼容性的问题。
    即:持有 src类,实现 dst 类接口,完成src->dst的适配。
    (根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。)
    Adapter类如下:

     1 /**
     2  * @Author: guodong
     3  * @Date: 2021/3/1 15:25
     4  * @Version: 1.0
     5  * @Description:
     6  */
     7 public class VoltageAdapter2 implements Voltage5 {
     8 
     9     private Voltage220 mVoltage220;
    10 
    11     public VoltageAdapter2(Voltage220 voltage220) {
    12         mVoltage220 = voltage220;
    13     }
    14 
    15     @Override
    16     public int output5V() {
    17         int dst = 0;
    18         if (null != mVoltage220) {
    19             int src = mVoltage220.output220V();
    20             System.out.println("对象适配器工作,开始适配电压");
    21             dst = src / 44;
    22             System.out.println("适配完成后输出电压:" + dst);
    23         }
    24         return dst;
    25     }
    26     
    27 }

    测试代码:

    1     public static void main(String[] args) {
    2         System.out.println("\n===============对象适配器==============");
    3         VoltageAdapter2 voltageAdapter2 = new VoltageAdapter2(new Voltage220());
    4         Mobile mobile2 = new Mobile();
    5         mobile2.charging(voltageAdapter2);
    6     }

    输出:

    ===============对象适配器==============
    我是220V
    对象适配器工作,开始适配电压
    适配完成后输出电压:5
    电压刚刚好5V,开始充电

    类图:

    小结:
    对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。根据合成复用原则,组合大于继承,
    所以它解决了类适配器必须继承src的局限性问题,也不再强求dst必须是接口。同样的它使用成本更低,更灵活。
    (和装饰者模式初学时可能会弄混,这里要搞清,装饰者是对src的装饰,使用者毫无察觉到src已经被装饰了(使用者用法不变)。 这里对象适配以后,使用者的用法还是变的。
    即,装饰者用法: setSrc->setSrc,对象适配器用法:setSrc->setAdapter.)

    郭慕荣博客园
  • 相关阅读:
    Do You See Me? Ethical Considerations of the Homeless
    ELDER HOMELESSNESS WHY IS THIS AN ISSUE?
    Endoflife support is lacking for homeless people
    html内联框架
    html字体
    html块 div span
    html列表
    html表格
    SQL Server管理员专用连接的使用   作为一名DBA,经常会处理一些比较棘手的服务无响应问题,鉴于事态的严重性,多数DBA可能直接用“重启”大法,以便尽快的恢复生产环境的正常运转,但是多数情况
    如何配置最大工作线程数 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/jelly12345/p/14463956.html
Copyright © 2011-2022 走看看