首页 > 其他分享 >设计模式:代理、装饰和适配器模式的区别

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

时间:2024-07-28 18:18:18浏览次数:6  
标签:对象 适配器 代理 模式 接口 设计模式 装饰

结构对比

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

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

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

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

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

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

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

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

本质对比

适配器模式的本质

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

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

代理模式的本质

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

代理模式的运行逻辑:

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

装饰模式的本质

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

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

 

标签:对象,适配器,代理,模式,接口,设计模式,装饰
From: https://www.cnblogs.com/TheGCC/p/18328628

相关文章

  • Postman中的代理艺术:配置与使用指南
    Postman中的代理艺术:配置与使用指南在API开发和测试过程中,代理服务器常用于捕获、检查、修改请求和响应。Postman作为一个流行的API开发工具,内置了代理服务器功能,使得测试人员可以方便地查看和修改通过代理的流量。本文将详细介绍如何在Postman中配置和使用代理服务器。代......
  • 永结无间Ⅲ--引入人工智能检查代理
    软件行业长期以来一直在寻求增强质量保证方法。虽然单元测试等传统方法提供了基础,但它们只是触及全面质量控制的表面。多年来,我们已经从手动测试发展到自动化测试,由人类专家创建和维护测试脚本。最近,DevOps实践和可观察性工具实现了对应用程序行为的基本自动分析。然而,这些组......
  • UFO:革新Windows操作系统交互的UI聚焦代理
    人工智能咨询培训老师叶梓转载标明出处人机交互的便捷性和效率直接影响着我们的工作和生活质量。尽管现代操作系统如Windows提供了丰富的图形用户界面(GUI),使得用户能够通过视觉和简单的点击操作来控制计算机,但随着应用程序功能的日益复杂化,用户在执行跨应用任务时仍面临着挑......
  • Linux让远程服务器代理IPv6流量
    使用场景本地机器只能访问IPv4网络。远程服务器能访问IPv4网络,也能访问IPv6网络。这篇博客介绍如何让远程服务器代理本地机器的IPv6流量,从而让本地机器也能访问IPv6网络。主要思路在远程服务器上创建一个netns,搭IPv6NAT,这样netns里面就能通过IPv6NAT访问公网。然后在netns和......
  • nginx 配置代理服务地址最后多加反斜杠和不加反斜杠的区别
    在使用Nginx配置代理服务时,地址最后是否添加反斜杠(/)会对代理的URL处理产生影响。1.地址最后不加反斜杠当配置的代理服务地址最后没有反斜杠时,Nginx会将请求的URL路径原封不动地传递给后端服务器。例如:location/backend/{proxy_passhttp://backend-server;}请......
  • 从零手写实现 nginx-33-http_proxy 代理验证测试
    前言大家好,我是老马。很高兴遇到你。我们为java开发者实现了java版本的nginxhttps://github.com/houbb/nginx4j如果你想知道servlet如何处理的,可以参考我的另一个项目:手写从零实现简易版tomcatminicat手写nginx系列如果你对nginx原理感兴趣,可以阅读:从零......
  • 常用设计模式-单例模式(Singleton pattern)
    常用设计模式-单例模式(Singletonpattern)一、单例模式目的使用单例模式第一步要了解其作用,单例理解为一个实例(oneinstance)。保证一个类只有一个它的实例。在实际开发中,如线程池,数据库连接对象等。二、实现思路为了保证oneclassoneinstance①则需要保证实例全局唯一,保......
  • Spring中使用到的设计模式及其源码分析
    前言众所周知,Spring框架是一个强大而灵活的开发框架。这不,上次的面试刚问到这些,没防住!!!因此下来总结一下。这篇文章主要介绍Spring中使用到的设计模式,自己做个面试复盘,同时希望能帮助到其他小伙伴儿们。工厂模式相信大家面试题都背过,Spring通过工厂模式来创建和管理Bean......
  • nginx 代理php
    centos7.6nginx编译安装./configure--prefix=/data/apps/nginx\--user=nginx\--group=nginx\--with-http_stub_status_module\--with-http_ssl_module\--with-http_gzip_static_module\--with-stream\--with-http_v2_module\--with-http_realip_mo......
  • 【golang设计模式】—— 外观模式
    模式定义外观模式(FacadePattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调......