设计模式:代理、装饰和适配器模式的区别

news/2024/11/15 20:05:21/文章来源:https://www.cnblogs.com/TheGCC/p/18328628

结构对比

讲实话,博主当初学习完整设计模式时,这三种设计模式单独摘哪一种都是十分清晰和明确的,但是随着模式种类的增加,在实际使用的时候竟然会出现恍惚,例如读开源代码时,遇到不以模式命名规范的代码时,一时难以说清具体是使用的这三种里的哪一种。

之所以会出现混淆的原因是,三种模式的实现都是基于面向接口这一思想,三种模式都是针对某一个具体的接口实现,并在其实现类上用一个对象对另一个对象提供间接访问。

基于混淆点,从类图上来看,适配器模式就可以最先被区别出来,适配器的类结构图

从类图上来看,适配器的主角是Adapter这个类,这个类与目标接口是实现关系,但是Adaptee则不同,它可以是一个接口,也可以是一个具体的类,它是与Target平级的一个对象,与Target毫无关系,而Adapter与它的关系是对象组合,是Adaptee作为Adapter的一个内部成员变量,Adapter的目的是将 Adaptee适配为Target。

相比于适配器模式,代理模式和装饰模式反而更容易被混淆, 混淆的原因是二者都是基于一个公共接口,且主角类(Proxy和Decorator)又都是以组合对象的形式,对目标对象(RealSubject和ConcreteComponent)进行二次操作。实现上来看,两者十分相似。

但是注意,这里还是有不同,

  • 代理模式是代理对象(Proxy)对实际被代理对象(RealSubject)的间接访问,是对公共接口的实现类提供间接访问;
  • 而装饰模式的装饰类是对被装饰接口或者说被装饰基类(Component)提供间接访问,不是对接口(Component)的实现类提供间接访问

也就是说,两者提供间接访问的对象不同,一个(代理模式)是基于具体的类,而另一个(装饰模式)是基于抽象的接口 。这也是为什么只可以使用一次的request对象要基于装饰模式提供封装来达到二次使用的原因(详细可翻阅设计模式:从HttpServletRequestWrapper了解装饰者模式),基于抽象接口提供的间接访问是不会破坏具体对象的内容。

本质对比

适配器模式的本质

适配器模式的主要功能是进行转换匹配,目的是复用已有的功能,而不是来实现新的接口。也就是说,客户端需要的功能应该是已经实现好了的,不需要适配器模式来实现,适配器模式主要负责把不兼容的接口转换成客户端期望的样子就可以了。

适配器的本质是转换功能,以提高复用性。不同于代理和装饰,适配器中的目标对象可能与需要适配的对象毫无关系,适配过程中代码甚至是全量的重写,它的目标是将两个内容沿其中某个为主进行融合。

代理模式的本质

代理模式是通过创建一个代理对象,用这个代理对象去代表真实的对象,客户端得到这个代理对象后,对客户端并没有什么影响,就跟得到了真实对象一样来使用。当客户端操作这个代理对象的时候,实际上功能最终还是会由真实的对象来完成,只不过是通过代理操作的,也就是客户端操作代理,代理操作真正的对象。
正是因为有代理对象夹在客户端和被代理的真实对象中间,相当于一个中转,那么在中转的时候就有很多花招可以玩,比如,判断一下权限,如果没有足够的权限那就不进行中转了,或者中转到别的操作中。

代理模式的运行逻辑:

代理模式的本质是控制对象访问。核心在于Proxy角色, 类似于中间商,是目标对象的一个“前沿发言人”,你想要访问目标对象,或者购买目标厂家的商品,必须从我代理商这里走, 我甚至可以不创建被代理对象,自己冒充被代理对象(直接以贴牌产品当作目标产品卖你)。

装饰模式的本质

装饰模式能够实现动态地为对象添加功能,是从一个对象外部来给对象增加功能,相当于是改变了对象的外观。当装饰过后,从外部使用系统的角度看,就不再是使用原始的那个对象了,而是使用被一系列的装饰器装饰过后的对象。这样就能够灵活地改变一个对象的功能,只要动态组合的装饰器发生了改变,那么最终所得到的对象的功能也就发生了改变。从这一点上来讲,代理模式也可以满足,但是不同的是,装饰模式这里有一个代理无法越过的原则,那就是代理模式必须有目标对象,否则装饰就无从谈起。

装饰模式的本质是通过组合来加强目标对象的能力,是对象能力的延申。装饰模式是在原有对象的基础上进行外层包装,可以对目标对象的每一个方法都进行前置、后置的补充和加强,但是本质上并没有改变原对象,是一种扩展思维,这一点可以参考AOP的思想。

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nand2tetris_hack计算机

构建Hack CPU,然后将CPU与RAM集成在一起,创建一个能够执行Hack机器语言的通用16位计算机终于来到了这一步!! 前文里,我们学习了hack编程语言,大概知道需要实现的hack计算机是什么样子,需要实现哪些功能。同时在更早的时候,我们建造了ALU和RAM组件,加上老师内置的ROM和…

暑假集训csp提高模拟10

赛时 rank 19,T1 0,T2 25 T3 10 T4 100 T3 挂了10pts? 数学专场,套路专场,烧脑专场。 幸亏我还有缓存的李超树博客,最后一个小时就溜了去打数据结构。 数学好难,拜谢数学。 T1 黑暗型高松灯 Company Acquisitions 要用势能分析,鞅的停时定理。由于赛时这个放T1非常逆天,…

Java-002

final关键字 final 关键字是最终的意思,可以修饰(类、方法、变量) 修饰类:该类被称为最终类,特点是不能被继承了。 修饰方法:该方法被称为最终方法,特点是不能被重写了。 修饰变量:该变量只能被赋值一次。 final修饰的变量必须赋值,要么在定义时赋值,要么在构造器中赋…

Java-001

Java入门 IDEA优化idea插件 翻译、阿里巴巴代码规范指导IDEA debug使用 Step into:单步执行(一行一行代码执行),如果遇到子函数,就会进入子函数,并且继续单步执行。就是每一行需要执行的代码都不跳过,一行一行进行。 Step over:在单步执行的时候,如果遇到子函数,并不…

ComfyUI插件:ComfyUI Impact 节点(二)

前言: 学习ComfyUI是一场持久战,而 ComfyUI Impact 是一个庞大的模块节点库,内置许多非常实用且强大的功能节点 ,例如检测器、细节强化器、预览桥、通配符、Hook、图片发送器、图片接收器等等。通过这些节点的组合运用,我们可以实现的工作有很多,例如自动人脸检测和优化修…

java-03

集合进阶 集合容器中只能存放对象,基本数据类型需要使用对应的包装类 Collection单列集合 collection集合体系 collection常用方法package com.itheima.d1_collection;import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.…

Nuxt.js 路由管理:useRouter 方法与路由中间件应用

title: Nuxt.js 路由管理:useRouter 方法与路由中间件应用 date: 2024/7/28 updated: 2024/7/28 author: cmdragon excerpt: 摘要:本文介绍了Nuxt 3中useRouter方法及其在路由管理和中间件应用中的功能。内容包括使用useRouter添加、移除路由,获取路由信息,基于History …

java-01

Java入门 IDEA优化idea插件 翻译、阿里巴巴代码规范指导IDEA debug使用 Step into:单步执行(一行一行代码执行),如果遇到子函数,就会进入子函数,并且继续单步执行。就是每一行需要执行的代码都不跳过,一行一行进行。 Step over:在单步执行的时候,如果遇到子函数,并不…

帝国CMS后台登录错误5次限制的解决办法

第一步,打开 /e/config/config.php 文件找到:loginnum ,这一项,将值由5改大一点即可。loginnum=>5,logintime=>60,logintime 就是锁定时间。扫码添加技术【解决问题,仅需10元起】专注中小企业网站建设、网站安全12年。熟悉各种CMS,精通PHP+MYSQL、HTML5、CSS3、Jav…

eyoucms如何搬家?易优cms搬家教程

1,本地备份数据库 2,删除install_********目录下的install.lock文件 3,再改名install_1540256968 为install 4,删除data/runtime所有文件夹 5,打包根目录下所有文件,上传空间解压即可安装扫码添加技术【解决问题,仅需10元起】专注中小企业网站建设、网站安全12年。熟悉…

安装界面不能正常显示

错误记录: 安装界面不能正常显示错误原因: 运行环境有问题解决方案: 运行环境有问题,使用记事本打开PHP配置文件php.ini: 设置short_open_tag = On 然后重启apache或iis设置才能生效。扫码添加技术【解决问题,仅需10元起】专注中小企业网站建设、网站安全12年。熟悉各种C…

织梦dedecms数据库连接文件位置

一、织梦CMS(dedecms)的数据库连接文件位置:织梦CMS V5.1 在include\config_base.php织梦CMS V5.3 在\data\common.inc.php织梦CMS V5.5 在\data\common.inc.php织梦CMS V5.6 在\data\common.inc.php织梦CMS V5.7 在\data\common.inc.php 二、织梦CMS(dedecms)的数据库连接文件…