装饰器模式、代理模式、适配器模式对比

装饰器模式、代理模式和适配器模式都是结构型设计模式,它们的主要目标都是将将类或对象按某种布局组成更大的结构,使得程序结构更加清晰。这里将装饰器模式、代理模式和适配器模式进行比较,主要是因为三个设计模式的类图结构相似度较高、且功能上存在一定的相似度。接下来将一步步说明。

装饰器模式

装饰器模式是一种结构型设计模式,用来动态地给一个对象增加一些额外的职责,即增加该对象额外的功能,其别名为包装器(Wrapper)。在装饰器模式中,会定义一个装饰器类,声明了一个指向被封装对象的引用成员变量,并定义了可动态添加到被封装对象的具体行为。其类图表示如下:

请添加图片描述

从类图结构上来说,装饰器模式并没有直接修改对象,而是在不影响对象的情况下,以动态、透明的方式给单个对象添加职责。就增加对象功能来说,装饰器模式比生成子类实现更为灵活。
装饰器模式主要适用于需要给对象动态地增加一些额外职责的场景。装饰器能将业务逻辑组织为层次结构,开发者可为各层创建一个装饰器,在运行时将各种不同逻辑组合成对象。特别是当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时,可以考虑使用装饰器模式。不能采用继承的情况主要有三类:第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是因为类定义不能继承(如final类);第三类是需要扩展的类来源于三方件,对于三方件的代码,如无特殊说明,是不建议使用继承来扩展功能的。
由于被装饰对象和装饰对象可以独立变化,用户可以根据需要增加新的被装饰类和装饰类,原有代码无须改变,这符合"开闭原则"。相比通过继承关系扩展对象的功能,装饰器模式可以提供比继承更多的灵活性,可以在不创建新子类的前提下,扩展对象的行为。但是,装饰器也带来代码复杂度上升的问题。使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,同时还将产生很多具体装饰类。这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难度。此外,装饰器模式比继承更加灵活,也同时意味着装饰器模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

代理模式

代理模式是一种结构型设计模式,用来为一个对象提供一种代理以控制对该对象的访问,即通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。代理对象控制着对于原对象的访问,并允许在将请求提交给原对象前后进行一些处理。为使用代理对象控制对原对象的访问,需要创建一个代理类并封装对原对象的访问。其类图表示如下:

请添加图片描述

代理模式适用于各种需要代理的场景,如远程代理、虚拟代理、缓存代理、动态代理等等。以动态代理为例,对于基于Spring框架开发的应用来说,Spring提供的AOP功能,可以看成是动态代理的一种应用。AOP通过切面的设计,可以在不影响对象的前提下,动态的增加代理完成对象的功能增加。
代理模式,在访问对象时引入了一定程度的间接性。因为可以在不对原对做出修改的情况下创建新代理,所以代理模式符合开闭原则。但代理模式的设计,也带来了代码复杂度上升的问题。实现代理模式需要额外的工作,有些代理模式的实现非常复杂(如动态代理)。此外,由于在客户端和真实对象之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢,从而带来服务响应的延迟。但是,这部分影响是极小的。
从类图结构上来说,装饰器模式和代理模式的相似度极高,但是两者还是有一定的差异。如果说装饰器模式的重心是动态地给对象增加一些职责模式,那么代理模式的重心则是通过代理对象间接地访问实际对象,并在代理过程中添加一些额外的逻辑或控制。代理模式主要应用于对象访问困难或复杂、或无法直接访问等场景。简言之,装饰器模式主要关注增强对象的功能,而代理模式则更多关注对对象访问的控制,并不直接增强对象的功能。

适配器模式

适配器模式是一种结构型设计模式,用于将一个类的接口转换成用户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器。根据适配器是根据继承方式,还是组合方式和待适配的类进行交互,可以将
适配器模式分为对象适配器和类适配器两种实现。对象适配器类图表示如下:

请添加图片描述

类适配器类图表示如下:

请添加图片描述

从类图结构上可以看到,对象适配器和类适配器的唯一差别就是适配器类(Adapter)和待适配类(Adaptee)的关系。对于类适配器来说,适配器类作为待适配类的子类,对原有方法进行了重写。而对于对象适配器来说,适配器类将待适配器类作为其成员,通过调用待适配器类的接口,完成了原有方法的重写。在实际的应用中,对于需要使用适配器的场景,应优先选用对象适配器。只有在对象适配器不合适的场景下,才考虑使用类适配器。如需要复用这样一些类,他们处于同一个继承体系,并且他们又有了额外的一些共同的方法,这时类适配器就比对象适配器更适合。
适配器模式主要适用于需要使用某个现有类,但是这个现有类的接口不符合系统的需要,或想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类一起工作等场景。适配器模式通过创建一个中间层类,可将其作为代码与遗留类、第三方类或提供接口的类之间的转换器。
适配器可以让接口不兼容的对象相互合作。通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码,实现了目标类和适配者类的解耦。且可以将接口或数据转换代码从目标类主要业务逻辑中分离出来,符合单一职责原则。但是,适配器模式也带来了代码整体复杂度上升的问题,开发者需要新增一系列接口和类。
适配器模式和装饰器模式都被称为包装器,但是两者适用的场合不同。适配器模式的主要目的是将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起协作。装饰器模式则是强调给对象增加一些新的行为或责任。适配器模式重点关注接口转换和兼容性,而装饰器模式则重点关注为对象动态地添加新的行为或责任。

装饰器模式、代理模式和适配器模式对比

无论装饰模式、代理模式和适配器模式,都是结构型设计模式。其主要职责都是将将类或对象按某种布局组成更大的结构,使得程序结构更加清晰。从类图结构上来说,装饰器模式和代理模式和对象适配器的结构上差异不大,都是通过一个外部类去组合目标类,并封装其行为。从功能上来说,装饰器模式关注的是给对象增加一些新的行为或责任。相比基于继承关系扩展对象的功能,装饰器模式可以提供比继承更多的灵活性,可以在不创建新子类的前提下,扩展对象的行为。代理模式更多的关注对象访问的控制,并不直接增强对象的功能。通过代理对象间接地访问实际对象,并在代理过程中添加一些额外的逻辑或控制。而适配器模式则关注接口转换或接口兼容性。通过将一个类的接口转换成客户端所期望的另一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的类可以一起协作。
在实际的应用中,针对装饰器模式、代理模式和适配器模式的选用上,还是要从功能上出发,因为三个设计模式在类图结构上差异并不大。通过其应用场景选择合适的设计模式,如对于对象功能增强的场景,选用装饰器模式,对于对象访问控制的场景,选用代理模式,对于接口的转换或兼容的场景,选用适配器模式。

参考

https://yiyan.baidu.com/ 文心一言
https://blog.csdn.net/kingmax54212008/article/details/107294704 OOAD-设计模式(四)结构型模式之适配器、装饰器、代理模式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/581854.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

10分钟了解数据质量管理-奥斯汀格里芬 Apache Griffin

在不重视数据质量的大数据发展时期,Griffin并不能引起重视,但是随着数据治理在很多企业的全面开展与落地,数据质量的问题开始引起重视。 1.Griffin简介 Griffin是一个开源的大数据数据质量解决方案,由eBay开源,它支持…

httpClient提交报文中文乱码

httpClient提交中文乱码,ContentType类型application/json 指定提交参数的编码即可 StringEntity se new StringEntity(paramBody.toJSONString(),"UTF-8");se.setContentType("application/json");context.httpPost.setHeader("Cookie&…

【PPT设计】颜色对比、渐变填充、简化框线、放大镜效果、渐变形状配图、线条的使用

目录 图表颜色对比、渐变填充、简化框线放大镜效果渐变形状配图 线条的使用区分标题与说明信息区分标题与正文,区分不同含义的内容**聚焦****引导****注解****装饰** 图表 颜色对比、渐变填充、简化框线 小米汽车正式亮相!你们都在讨论价格,我全程只关…

【实时数仓架构】方法论(未完)

笔者不是专业的实时数仓架构,这是笔者从其他人经验和网上资料整理而来,仅供参考。写此文章意义,加深对实时数仓理解。 实时数仓背景和场景 一、实时数仓架构技术演进 1.1、四种架构演进 1)离线大数据架构 一种批处理离线数据分…

State.initState() must be a void method without an `async` keyword错误解析

文章目录 报错问题报错的代码 错误原因解决方法解析 另外的方法 报错问题 State.initState() must be a void method without an async keyword如下图: 报错的代码 报错的代码如下: overridevoid initState() async{super.initState();await getConf…

springboot权限验证学习-上

创建maven项目 创建父工程 这类项目和原来项目的区别在于&#xff0c;打包方式是pom 由于pom项目一般都是用来做父项目的&#xff0c;所以该项目的src文件夹可以删除掉。 创建子工程 子工程pom.xml 父工程pom.xml 添加依赖 父工程导入依赖包 <!--导入springboot 父工程…

李沐70_bert微调——自学笔记

微调BERT 1.BERT滴哦每一个词元返回抽取了上下文信息的特征向量 2.不同的任务使用不同的特性 句子分类 将cls对应的向量输入到全连接层分类 命名实体识别 1.识别应该词元是不是命名实体&#xff0c;例如人名、机构、位置 2.将非特殊词元放进全连接层分类 问题回答 1.给…

fetch请求后端返回文件流,并下载。

前端&#xff1a; <script src"~/layui/layui.js"></script> <script src"~/Content/js/common/js/vue.min.js"></script> <script src"~/Content/js/common/js/jquery-1.10.2.min.js"></script><styl…

[论文笔记]GAUSSIAN ERROR LINEAR UNITS (GELUS)

引言 今天来看一下GELU的原始论文。 作者提出了GELU(Gaussian Error Linear Unit,高斯误差线性单元)非线性激活函数&#xff1a; GELU x Φ ( x ) \text{GELU} x\Phi(x) GELUxΦ(x)&#xff0c;其中 Φ ( x ) \Phi(x) Φ(x)​是标准高斯累积分布函数。与ReLU激活函数通过输入…

pycharm配置wsl开发环境(conda)

背景 在研究qanything项目的过程中&#xff0c;为了进行二次开发&#xff0c;需要在本地搭建开发环境。然后根据文档说明发现该项目并不能直接运行在windows开发环境&#xff0c;但可以运行在wsl环境中。于是我需要先创建wsl环境并配置pycharm。 wsl环境创建 WSL是“Windows Su…

【多模态大模型】AI对视频内容解析问答

文章目录 1. 项目背景2. 直接对视频进行解析进行AI问答&#xff1a;MiniGPT4-Video2.1 MiniGPT4-Video效果 3. 对视频抽帧为图片再进行AI问答3.1 视频抽帧3.2 图片AI问答3.2.1 阿里通义千问大模型 Qwen-vl-plus3.2.2 Moonshot 1. 项目背景 最近在做一个项目,需要使用AI技术对视…

DDP示例

https://zhuanlan.zhihu.com/p/602305591 https://zhuanlan.zhihu.com/p/178402798 关于模型保存与加载 &#xff1a; 其实分为保存 有module和无module2种 &#xff1b; &#xff08;上面知乎这篇文章说带时带module) 关于2种带与不带的说明&#xff1a; https://blog.csdn.…

69、栈-有效的括号

思路&#xff1a; 有效的括号序列是指每个开括号都有一个对应的闭括号&#xff0c;并且括号的配对顺序正确。 比如&#xff1a;({)} 这个就是错误的&#xff0c;({}) 这个就是正确的。所以每一个做括号&#xff0c;必有一个对应的右括号&#xff0c;并且需要顺序正确。这里有…

Meilisearch 快速入门(Windows 环境) 搜索引擎 语义搜索

Meilisearch 快速入门(Windows 环境)# 简介# Meilisearch 是一个基于 rust 开发的,快速的、完全开源的轻量级搜索引擎。它的数据存储基于磁盘与内存映射,不受 RAM 限制。在一定数量级下,搜索速度不逊于 Elasticsearch。 下载# 官方服务端包下载地址:github.com/meili…

常用图像加密技术-流密码异或加密

异或加密是最常用的一种加密方式&#xff0c;广泛的适用于图像处理领域。这种加密方式依据加密密钥生成伪随机序列与图像的像素值进行异或操作&#xff0c;使得原像素值发生变化&#xff0c;进而使得图像内容发生变化&#xff0c;达到保护图像内容的目的。 该加密方法是以图像…

鸿蒙OpenHarmony【小型系统 烧录】(基于Hi3516开发板)

烧录 针对Hi3516DV300开发板&#xff0c;除了DevEco Device Tool&#xff08;操作方法请参考烧录)&#xff09;外&#xff0c;还可以使用HiTool进行烧录。 前提条件 开发板相关源码已编译完成&#xff0c;已形成烧录文件。客户端&#xff08;操作平台&#xff0c;例如Window…

深度学习模型的优化和调优de了解

深度学习模型的优化和调优&#xff1a;随着深度学习应用的广泛&#xff0c;优化和调优神经网络模型成为了一个重要的问题。这包括选择合适的网络架构、调整超参数、应对过拟合等。 深度学习模型的优化和调优是指在训练神经网络模型时&#xff0c;通过一系列技术和方法来提高模型…

FTP 文件传输协议

FTP 文件传输协议 作用 用来传输文件的 FTP协议采用的是TCP作为传输协议&#xff0c; 21号端口用来传输FTP控制命令的&#xff0c; 20号端口用来传输文件数据的 FTP传输模式&#xff1a; 主动模式&#xff1a; FTP服务端接收下载控制命令后&#xff0c;会主动从tcp/20号端口…

C语言之详细讲解文件操作

什么是文件 与普通文件载体不同&#xff0c;文件是以硬盘为载体存储在计算机上的信息集合&#xff0c;文件可以是文本文档、图片、程序等等。文件通常具有点三个字母的文件扩展名&#xff0c;用于指示文件类型&#xff08;例如&#xff0c;图片文件常常以KPEG格式保存并且文件…

修改word文件的创作者方法有哪些?如何修改文档的作者 这两个方法你一定要知道

在数字化时代&#xff0c;文件创作者的信息往往嵌入在文件的元数据中&#xff0c;这些元数据包括创作者的姓名、创建日期以及其他相关信息。然而&#xff0c;有时候我们可能需要修改这些创作者信息&#xff0c;出于隐私保护、版权调整或者其他实际需求。那么&#xff0c;有没有…