《设计模式之禅》笔记摘录 - 5.代理模式

代理模式的定义

代理模式(Proxy Pattern)是一个使用率非常高的模式,其定义如下:Provide a surrogate or placeholder for another object to control access to it. (为其他对象提供一种代理以控制对这个对象的访问。)

代理模式的通用类图:

代理模式也叫做委托模式,它是一项基本设计技巧。许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式,而且在日常的应用中,代理模式可以提供非常好的访问控制。在一些著名开源软件中也经常见到它的身影,如Struts2的Form元素映射就采用了代理模式(准确地说是动态代理模式)。我们先看一下类图中的三个角色的定义:

Subject抽象主题角色抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。

RealSubject具体主题角色做被委托角色、被代理角色。它才是冤大头,是业务逻辑的具体执行者。

Proxy代理主题角色也叫做委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并日在真实主题角色处理完毕前后做预处理和善后处理工作。

代理模式的应用

代理模式的优点

职责清晰。真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。

高扩展性。角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,都逃不脱如来佛的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用。

智能化。在我们以上的讲解中还没有体现出来,不过在我们以下的动态代理章节中你就会看到代理的智能化有兴趣的读者也可以看看Struts是如何把表单元素映射到对象上的。

代理模式的使用场景

我相信第一次接触到代理模式的读者肯定很郁闷,为什么要用代理呀?想想现实世界吧,打官司为什么要找个律师?因为你不想参与中间过程的是是非非,只要完成自己的答辩就成,其他的比如事前调查、事后追查都由律师来搞定,这就是为了减轻你的负担。代理模式的使用景非常多,大家可以看看Spring AOP,这是一个非常典型的动态代理。

代理模式的扩展

普通代理

首先说普通代理,它的要求就是客户端只能访问代理角色,而不能访问真实角色,这是比简单的。

在该模式下,调用者只知代理而不用知道真实的角色是谁,屏蔽了真实角色的变更对高层模块的影响,真实的主题角色想怎么修改就怎么修改,对高层次的模块没有任何的影响,只要你实现了接口所对应的方法,该模式非常适合对扩展性要求较高的场。当然,在实际的项目中,一般都是通过约定来禁止new一个真实的角色,这也是一个非常好的方案。

注意普通代理模式的约束问题,尽量通过团队内的编程规范类约束,因为每一个主题类是可被重用的和可维护的,使用技术约束的方式对系统维护是一种非常不利的因素。

强制代理

强制代理在设计模式中比较另类,为什么这么说呢?一般的思维都是通过代理找到真实的角色,但是强制代理却是要"强制",你必须通过真实角色查找到代理角色,否则你不能访问。

在接口上增加了一个getProxy方法,真实角色GamePlayer可以指定一个自己的代理,除了代理外谁都不能访问。

虽制代理的概念就是要从真实角色查找到代理角色,不允许且接访问真实角色。高层模块只要调用getProxy就可以访问真实角色的所有方法,它根本就不需要产生一个代理出来,代理的管理已经由真实角色自己完成。

代理是有个性的

一个类可以实现多个接口,完成不同任务的整合。也就是说代理类不仅仅可以实现主题接口,也可以实现其他接口完成不同的任务,而且代理的目的是在目标对象方法的基础上作增强,这种增强的本质通常就是对目标对象的方法进行拦截和过滤。

动态代理

什么是动态代理?动态代理是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。相对来说,自己写代理类的方式就是静态代理。

最佳实践

代理模式应用得非常广泛,大到一个系统框架、企业平台,小到代码片段、事务处理,稍不留意就用到代理模式。可能该模式是大家接触最多的模式,而且有了AOP大家写代理就更加简单了,有类似Spring AOP和AspectJ这样非常优秀的工具,拿来主义即可!不过,大家可以看看源代码,特别是调试时,只要看到类们$Proxy0这样的结构,你就应该知道这是一个动态代理了。

友情提醒,在学习AOP框架时,弄清楚几个名词就成:切面(Aspect)、切入点(JoinPoint)、通知(Advice)、织入(Weave)就足够了,理解了这几个名词,应用时你就可以游刃有余了!

相关推荐
丝斯20116 小时前
AI学习笔记整理(42)——NLP之大规模预训练模型Transformer
人工智能·笔记·学习
凉、介8 小时前
深入 QEMU Guest Agent:虚拟机内外通信的隐形纽带
c语言·笔记·学习·嵌入式·虚拟化
GISer_Jing8 小时前
AI Agent 目标设定与异常处理
人工智能·设计模式·aigc
njsgcs8 小时前
SIMA2 论文阅读 Google 任务设定器、智能体、奖励模型
人工智能·笔记
蔺太微9 小时前
组合模式(Composite Pattern)
设计模式·组合模式
云半S一9 小时前
pytest的学习过程
经验分享·笔记·学习·pytest
AI视觉网奇9 小时前
ue5.7 配置 audio2face
笔记·ue5
鱼跃鹰飞11 小时前
DDD中的防腐层
java·设计模式·架构
会员果汁12 小时前
15.设计模式-组合模式
设计模式·组合模式
崎岖Qiu12 小时前
【OS笔记35】:文件系统的使用、实现与管理
笔记·操作系统·存储管理·文件系统·os