设计模式复习(七)-------适配器模式

2023-11-02

1. 定义

将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
——《设计模式》GoF

  • 适配,即在不改变原有实现的基础上,将原先不兼容的接口转换为兼容的接口。
  • Adapter模式很像货物的包装过程:被包装的货物的真实样子被包装所掩盖和改变,因此有人把这种模式叫做包装(Wrapper)模式。事实上,大家经常写很多这样的Wrapper类,把已有的一些类包装起来,使之具有能满足需要的接口。
  • 适配器模式有类适配器模式和对象适配器模式两种。
  • 变化的是应用环境,从而要求不同的接口
  • 这种模式很常见,比如力扣上的设计题,我们写了一个类来完成题目要求的功能,可能里面用到了数组或者栈结构,在客户端看来,我们完成了这个功能。这时候,我们写的类就是Adapter类,数组或者栈就是被实现包装的角色Adaptee

2. 结构

2.1 对象适配器(推荐使用)

​ 客户端需要调用Request方法,而Adaptee没有该方法,为了使客户端能够使用Adaptee类,需要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例(对象),从而将客户端与Adaptee衔接起来。由于Adapter与Adaptee是组合关系,这决定了这个适配器模式是对象模式。

对象适配器的结构:

在这里插入图片描述

对象适配器的角色:

  • 目标(Target)角色:这是客户所期待的接口。目标接口可以是抽象类,也可以是接口。
  • 源(Adaptee)角色:需要被适配(实际完成工作)的类----源接口。
  • 适配器(Adapter)角色:通过在内部包装(Wrap)一个Adaptee对象,把源接口转换成目标接口。

对象适配器在类似C#、Java这样的不支持多继承的语言中应用较多。

对象适配器示例
利用ArrayList实现栈结构–ObjectAdapterStack(看看源码)

namespace ObjectAdapterStack{
    /// <summary>
    /// Target角色--堆栈的抽象接口--给出堆栈类的主要操作Request
    /// </summary>
    interface IStack {
        void   Push(object item); //入栈
        object Pop();  //出栈
        object Top();  //获取栈顶元素,但不作出栈操作
    }
}
namespace ObjectAdapterStack{
    /// <summary>
    /// Adapter--适配器,将Request转化为SpecificRequest
    /// </summary>
    class MyStack:IStack{
        /// <summary>
        /// Adaptee--动态数组,用于存储堆栈数据--被适配的对象
        /// </summary>
        private ArrayList list=null; 

        public MyStack()
        {
            list = new ArrayList();
        }

        /// <summary>
        /// 进栈操作--Request
        /// </summary>
        /// <param name="obj">进栈的元素</param>
        public void Push(object obj) 
        {
            list.Add(obj); //将用户对栈的操作转换为对动态数组(Adaptee对象)的操作--SpecificRequest
        }

        /// <summary>
        /// 出栈操作--Request
        /// </summary>
        /// <returns></returns>
        public object Pop()
        {
            object obj = list[list.Count - 1]; //取出栈顶元素--SpecificRequest
            list.RemoveAt(list.Count - 1); //删除栈顶元素--SpecificRequest

            return  obj;
        }

        /// <summary>
        /// 取栈顶元素--Request
        /// </summary>
        /// <returns></returns>
        public object Top()
        {
            return list[list.Count - 1]; //SpecificRequest
        }

    }
}

namespace ObjectAdapterStack{
    class Program{
        static void Main(string[] args){
            //客户端创建Adapter对象,也可以从参数传入
            IStack stack = new MyStack();
            
            //通过Adapter对象调用实际的Adaptee对象完成具体的操作
            stack.Push(1);
            int i = (int)stack.Pop();

            Console.WriteLine(i);
            Console.ReadLine();
        }
    }
}

2.2 类适配器

​ Adaptee类没有Request方法,而客户期待这个方法。为了使客户能够使用Adaptee类,提供一个中间环节,即Adapter类,Adapter类实现了Target接口,并继承自Adaptee,Adapter类的Request方法重新封装了Adaptee的SpecificRequest方法,实现了适配的目的。
​ 因为Adapter与Adaptee是继承的关系,所以这决定了这个适配器模式是类模式。

在这里插入图片描述

类适配器的角色:

  • 目标(Target)角色:这是客户所期待的接口。因为C#不支持多继承,所以Target必须是接口,不可以是类。
  • 源(Adaptee)角色:需要被适配的类。
  • 适配器(Adapter)角色:把源接口转换成目标接口。这一角色必须是类。
    客户端程序应该使用Target访问适配器(避免胖接口)!!!

示例: ClassAdapterStack

类适配器主要应用于类似于C++的支持多继承的语言。

​ 总的来说:对象适配器采用组合方式实现,而类适配器采用继承方式实现,按照优先使用组合的松耦合原则,应该优先考虑使用对象适配器。

3. 优缺点及适用环境

  • Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
  • 类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。
  • 对象适配器采用“对象组合”的方式,更符合松耦合精神。

这个模式介绍的很简单,复杂的没讲

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式复习(七)-------适配器模式 的相关文章

随机推荐

  • 如何在 Ubuntu 20.04 上安装 Visual Studio Code

    视觉工作室代码是微软开发的一款功能强大的开源代码编辑器 它具有内置的调试支持 嵌入式Git控制 语法突出显示 代码完成 集成终端 代码重构和片段 Visual Studio Code 是跨平台的 可在 Windows Linux 和 mac
  • 如何在 Debian 10 Linux 上安装 Webmin

    Webmin是一个用于管理 Linux 服务器的开源 Web 控制面板 它允许您管理系统用户 组 磁盘配额以及安装和配置 Web ssh ftp 电子邮件和数据库服务器 使用 Webmin 您几乎可以配置系统的每个方面 在本教程中 我们将向
  • 如何在 Ubuntu 18.04 上安装 Kvm

    KVM 基于内核的虚拟机 是内置于 Linux 内核中的开源虚拟化技术 它允许您运行多个基于 Linux 或 Windows 的隔离来宾虚拟机 每个来宾都有自己的操作系统和专用虚拟硬件 例如 CPU 内存 网络接口和存储 本指南介绍如何在
  • 如何在 Debian 10 上安装 Elasticsearch

    Elasticsearch 是一个开源分布式全文搜索和分析引擎 它支持 RESTful 操作 允许您实时存储 搜索和分析大量数据 Elasticsearch 是最流行的搜索引擎之一 为具有复杂搜索要求的应用程序 例如大型电子商务商店和分析应
  • (see DUPEFILTER_DEBUG to show all duplicates)

    出现 see DUPEFILTER DEBUG to show all duplicates 的原因 在爬虫出现了重复的链接 重复的请求 解决方法 在request添加dont filter True
  • 常见反爬虫方法以及怎样突破

    大家可能不知道 互联网中超过一半的流量是网络爬虫贡献的 若是网站不设置反爬虫机制 可能根本没法运营 于是都设置了各种各样的反爬虫机制 即使如此 网络爬虫还是有办法去突破 今天小编为大家介绍一些常见的反网络爬虫以及突破方法 1 动态页面限制
  • [阶段4 企业开发进阶] 7. 微服务--SpringCloud Alibaba

    文章目录 1 服务注册和配置中心Nacos 1 1 Nacos简介 1 2 Nacos作为服务注册中心 服务提供者注册 服务消费者注册和负载 服务注册中心对比 1 3 Nacos作为服务配置中心 基础配置 分类配置 DataID方案配置 G
  • 转载:中国电信、网通、联通ADSL用户必读:中国电信、网通、联通劫持dns(浏览器)解决方案

    中国电信 网通 联通ADSL用户必读 中国电信 网通 联通劫持dns 中国电信 网通 联通劫持ie浏览器 解决方案D 宽带连接有 也能上网但是本地连接一直显示为受限制的解决方法 我的电脑一直显示本地连接受限制或无连接而宽带连接能连上 这是为
  • Spring Cloud 集成Gson 包冲突

    昨天再引入包的时候 Run了下main直接报错 就知道是包版本冲突了 然后添加的包排除 启动是正常了 但是项目一跑方法直接抛出来 gson转换异常 所以又得放开 于是尝试下引入Gson包试试
  • 3D文档(BRD、MRD、PRD)怎么写

    3D文档 一般来说 BRD作为战略方向的制定 是最早产出的文档 而MRD则是在战略方向的基础上对市场进行的分析 同时对后续工作的方向进行一些说明和指导 也可以说是通过对市场环境 竞品的分析 明确用户定位和产品定位的过程 PRD则是在战略方向
  • rpm的安装和卸载

    1 安装rpm包 强制安装目录下所有rpm包 rpm ivh rpm force nodeps 2 卸载rpm包 rpm e 包名 rpm nodeps
  • Buck的振铃实验与分析

    上上期我们提到了buck电路的开关的振铃波形 本质原因是LC的阻尼振荡 文章偏理论 那BUCK到底是怎么产生尖峰振荡呢 要想把这个问题搞清楚 也很是不容易 所以文章有点长 请直接点赞转发加收藏 问题 本期主要分析以下这两个问题 1 死区时间
  • 缩尾处理 stata

    要求 对连续变量上下1 的分位数进行了缩尾处理 目录 安装 具体命令 疑问1 需要对所有变量缩尾吗 疑问2 面板数据每年的截面数据分别进行处理吗 还是这么多年都混在一起处理 安装 ssc install winsor2 结果发现自己卡在了第
  • android 绘图之Path与Paint详解 - 冷冷汤圆

    http www cnblogs com aibuli p efef9d774df97c553a8a0c0c3495ba35 html utm source tuicool utm medium referral
  • 注释转换小项目(c注释->到c++注释)

    首先欢迎阅读本文 注释转换小项目涉及到c语言对文件的操作 另外这个小项目还应该对各种情况都考虑到 将c语言注释转换为c 注释 经过分析思考 我得到证据要的注释转换有以下几类 我将之整理并放入一个文件里 起名input c 1 一般情况 in
  • 【JavaScript高级】函数相关知识:函数、纯函数、柯里化、严格模式

    文章目录 函数 函数对象的属性 arguments arguments转Array 箭头函数不绑定arguments 剩余参数 rest 纯函数 定义 纯函数的案例 作用和优势 柯里化 定义 优势 自动柯里化 组合函数 定义 组合函数的封装
  • QT信号与槽的6种连接方式以及传递参数为自定义参数时

    文章目录 前言 一 信号与槽的连接 二 connect的第五个参数 三 传递参数为自定义参数时 扩展 前言 QT提供了信号与槽机制来实现对象之间的通信 只有QObject及其派生类才能使用信号和槽机制 且在类之中还需要使用Q OBJECT宏
  • CVTE面试总结(全网面经,已收offer)

    CVTE面试总结 文章目录 CVTE面试总结 CVTE一面 CVTE二面 CVTE面试hr面准备工作 1 问工资 2 给前面两轮面试打分 3 家庭关系和谁最好 4 未来5 10年会做什么 怎么规划 5 有没有别的offer 6 如果给off
  • 专家讲解 Hadoop:HBASE松散数据存储设计

    http developer 51cto com art 201006 203833 htm 本节和大家一起学习一下Hadoop HBASE松散数据存储设计方面的内容 希望通过本节介绍大家能够掌握Hadoop HBASE松散数据存储设计的方
  • 设计模式复习(七)-------适配器模式

    1 定义 将一个类的接口转换成客户希望的另一个接口 Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 设计模式 GoF 适配 即在不改变原有实现的基础上 将原先不兼容的接口转换为兼容的接口 Adapter模式很像货