概念
在软件开发中,由于一些原因,客户端不想或不能直接访问一个对象,此时可以通过一个称为"代理"的第三者来实现间接访问。该方案对应的设计模式被称为代理模式。
代理模式(Proxy Design Pattern ) 原始定义是:让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问,并允许将请求提交给对象前后进行一些处理。
代理模式原理
代理(Proxy)模式分为三种角色:
- 抽象主题(Subject)类: 声明了真实主题和代理主题的共同接口,这样就可以保证任何使用真实主题的地方都可以使用代理主题,客户端一般针对抽象主题类进行编程。
- 代理(Proxy)类 : 提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以在任何时候访问、控制或扩展真实主题的功能。
- 真实主题(Real Subject)类: 实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
如下图。
结构图
代码片段
class ISubject { public: virtual void Handle() = 0; virtual ~ISubject() {} }; // 该类在当前进程,也可能在其他进程当中 class RealSubject : public ISubject { public: virtual void Handle() { // 只完成功能相关的操作,不做其他模块的判断 } }; // 在当前进程当中 只会在某个模块中使用 class Proxy1 : public ISubject { public: Proxy1(ISubject *subject) : _subject(subject) {} virtual void Handle() { // 在访问 RealSubject 之前做一些处理 //if (不满足条件) // return; _subject->Handle(); count++; // 在访问 RealSubject 之后做一些处理 } private: ISubject* _subject; static int count; };
优缺点
优点:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
- 代理对象可以扩展目标对象的功能;
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;
缺点:
- 增加了系统的复杂度;
代理模式使用场景
- 功能增强
当需要对一个对象的访问提供一些额外操作时,可以使用代理模式 - 远程(Remote)代理
实际上,RPC 框架也可以看作一种代理模式,GoF 的《设计模式》一书中把它称作远程代理。通过远程代理,将网络通信、数据编解码等细节隐藏起来。客户端在使用 RPC 服务的时候,就像使用本地函数一样,无需了解跟服务器交互的细节。除此之外,RPC 服务的开发者也只需要开发业务逻辑,就像开发本地使用的函数一样,不需要关注跟客户端的交互细节。 - 防火墙(Firewall)代理
当你将浏览器配置成使用代理功能时,防火墙就将你的浏览器的请求转给互联网;当互联网返回响应时,代理服务器再把它转给你的浏览器。 - 保护(Protect or Access)代理
控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
小结
代理模式应该是很常用的,不仅在代码中,也在日常生活中。看懂了吗?不懂,可以来学习学习。