代理模式
定义
代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而对象代理可以在客户端和目标对象中起到中介的作用。
要点
直白来说,代理模式就是代理对象具备真实对象的功能,并代替真实对象完成相应操作,并能在操作执行前后,对操作进行增强处理。其UML图如下所示:
图中主要角色有如下:
- Subject(抽象接口类):定义RealSubject和Proxy的共用接口,其实就是为了Proxy能够替代RealSubject
- RealSubject(具体实体):这是一个真实的对象,Proxy要代理的目的对象。
- Proxy(代理类):类内保存着一个具体实体的对象,使得能够访问实体,并提供与Subject的接口相同的接口。简单来说,可以理解为利用Proxy把RealSubject封装起来,用Proxy替代RealSubject,用户调用Proxy就是调用RealSubject。
代码实现
-
Subject
class Subject{ public: virtual void Request() = 0; };
-
RealSubject
class RealSubject : public Subject{ public: virtual void Request(){ cout << "Real Request" << endl; } };
-
Proxy
class Proxy : public Subject{ // 一定要先声明这是个空的 RealSubject * realSubject = nullptr; public: virtual void Request(){ // 创建对象的过程其实可以在构造函数中创建 在这里创建是为了方便 if(realSubject == nullptr){ realSubject = new RealSubject(); } realSubject->Request(); } };
-
Client
int main(){ Proxy * proxy = new Proxy(); proxy->Request() ; return 0; }
输出结果:
优点和缺点
优点
- 职责清晰。实现好内部结构就可以,具体客户要求由代理进行分化。
- 高扩展性。具体对象随时变化,只要实现了接口,代理无论如何都是可以使用的。
- 隔离性。代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
缺点
- 代理模式会造成系统设计中类的数量增加。
- 在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢。
- 增加了系统的复杂度。
应用场景
- 远程代理,一个对象在不同的地址空间提供局部代表,可以隐藏一个对象存在于不同地址空间的事实。
- 虚拟代理,创建开销很大的对象时,通过它来存放实例化需要很长时间的真实对象。比如说HTML加载时,页面通常不是一下子全加载出来的,而是根据所需加载的。
- 安全代理,控制真实对象访问的权限。
- 智能代理,当调用真实的对象时,代理处理另外的事,就是在代理中添加其他的功能。
拓展
普通代理
普通代理, 它的要求就是客户端只能访问代理角色, 而不能访问真实角色.
强制代理
一般的思维都是通过代理找到真实的角色, 但是强制代理却是要“强制”, 你必须通过真实角色查找到代理角色, 否则不能访问。
动态代理
实现阶段不用关心代理谁,而在运行阶段指定代理哪一个对象。