1、意图
- 为其他对象提供一种代理以控制对这个对象的访问
2、动机
-
为了只有在确实需要这个对象时才对它进行创建和初始化。提高程序响应速度。
3、适用性
- 远程代理(Remote Proxy) 为一个对象在不同的地址空间提供局部代表。
- 虚代理(Virtual Proxy)为开销很大的对象创建代理,使之可以按需创建。
- 保护代理(Protection Proxy) 控制对原始对象的访问。用于对象应该有不同的访问权限的时候。
- 智能指引(Smart Reference) 取代简单的指针,它在访问对象时执行一些附加的操作。其典型用途包括:
- Smart Pointers:对指向实际对象的引用计数,当该对象没有引用时,自动释放它。
- 当第一次引用一个持久对象时,将它装入内存。
- 在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能使用它。
4、结构
这是运行时刻一种可能的代理结构的对象图:
5、参与者
- Proxy
- 保存一个引用,使得代理可以访问实体。若RealSubject和Subject接口相同,Proxy会引用Subject。
- 提供一个与Subject的接口相同的接口,这样代理就可以用来代替实体。
- 控制对实体的存取,并可能负责创建和释放它。
- Remote Proxy 负责对其请求及其参数进行编码,并向不同地址空间的实体发送已编码的请求。
- Virtual Proxy 可以缓存实体的附加信息,以便延迟对它的访问。
- Protection Proxy 检查调用者是否具有实现一个请求所必须的访问权限。 - Subject
- 定义RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。 - RealSubject
- Proxy所代表的实体
6、协作
- 代理根据其种类,在适当的时机向Realsubject转发请求。
7、效果
- Proxy模式在访问对象时引入了一定程度的间接性。根据代理的类型,附加的间接性有多种用途:
1)Remote Proxy 可以隐藏一个对象存在于不同地址空间的事实。
2)Virtual Proxy 可以进行最优化,比如延迟对象创建。
3)Protection Proxy 和 Smart Reference 都允许在访问一个对象时有一些附加的内务处理。 - Proxy模式还可以对用户隐藏另一种称之为Copy-on-Write的优化方式,该优化与根据需要创建对象有关(Virtual Proxy)。
拷贝一个复杂且庞大的对象是一种开销很大的操作,如果这个对象拷贝根本没有被修改,那么这些开销就没有必要。用代理延迟这一拷贝过程,我们可以保证只有当这个对象被修改时才对它进行拷贝。
在实现copy-on-write时必须对实体进行引用计数。拷贝代理仅会增加引用计数。只有当用户请求一个修改该实体的操作时,代理才会真正的拷贝它。在这种情况下,代理还必须减少实体的引用计数。当引用的数目为0时,这个实体将被删除。
Copy-on-Write可以大幅度的降低拷贝庞大实体时的开销。
8、实现
- 重载C++中的存取运算符(-> 和 *) 重载这一运算符使你可以在撤销对一个对象的引用时执行一些附加操作。此时,代理的作用就像一个指针。
- 人工实现每一个代理操作,向实体转发请求。一般来说,所有的操作在向实体转发请求前都需要检验这个要求是否合法,原始对象是否存在等。
- Proxy并不总是需要知道实体的类型 若Proxy类能够完全通过抽象接口处理它的实体,则无须为每一个Realsubject类都生成一个Proxy类;Proxy类可以统一处理所有的Realsubject实体。但是如果Proxy类要实例化RealSubject,则需要知道其具体类型。
- 在实例化实体以前如何引用它?
9、相关模式
- Adapter:适配器Adapter为它所适配的对象提供一个不同的接口。而代理提供的接口是实体接口的一个子集。
- Decorator:Decorator为对象添加一个或多个功能,而代理则控制对象的访问。