模式概述
当我们无法访问某个对象、直接访问某个对象存在困难、在访问对象之前增加访问权限验证等情况时,我们可以引入一个代理对象进行间接访问。为了客户端使用的透明性,代理对象和真实对象需要实现共同的接口;代理模式定义如下:
代理模式(proxy):为其他对象提供一种代理以控制对这个对象的访问,其基本UML类图如下:
在UML类图中有以下几个角色:
CSubject类:定义了CRealSubject类和CProxy类的公共接口,这样在任何地方使用CRealSubject类对象都可用CProxy类对象来替代;这些公共接口也指明了CRealSubject类所拥有的接口;
CRealSubject类:定义了需要被访问的真实实体;
CProxy类:保存一个CRealSubject类对象的指针,这个指针指向真实访问实体;CProxy类除了实现公共接口外,还会增加其他的成员变量或者接口,以控制对真实对象的访问和其他特殊处理;
具体代码
#include "stdafx.h"
using namespace std;
//抽象类,代表代理对象和真实对象的公共接口
class CSubject
{
public:
CSubject(){};
virtual ~CSubject(){};
virtual void Request() = 0;
};
//真实类
class CRealSubject: public CSubject
{
public:
CRealSubject(){}
~CRealSubject(){}
virtual void Request()
{
cout <<"I am real subject." << endl;
}
};
//代理类
class CProxy:public CSubject
{
public:
CProxy():pRealSubject(NULL){}
~CProxy()
{
SAFE_DELETE_PTR(pRealSubject);
}
virtual void Request()
{
//访问真实对象前,增加特殊处理
PreRequst();
if (NULL == pRealSubject)
{
pRealSubject = new CRealSubject();
}
//访问真实实体
if (pRealSubject != NULL)
{
pRealSubject->Request();
}
}
void PreRequst()
{
cout << "I will transmit requst to real subject." << endl;
}
private:
CSubject* pRealSubject;//指向真实实体的指针
};
客户端代码:
int _tmain(int argc, _TCHAR* argv[])
{
CSubject* pSubjec = new CProxy;
//针对接口编程
pSubjec->Request();
SAFE_DELETE_PTR(pSubjec);
return 0;
}
运行结果:
I will transmit requst to real subject.
I am real subject.
代理模式应用
代理模式有以下几种常见的使用场合:
远程代理:远程代理为位于两个不同地址空间的对象访问提供了一种实现机制,可以将一些消耗资源较多的对象和操作移至性能更好的计算机上,提高系统的整体运行效率;使得客户端不用关心和远程服务器通信的操作,就像在同一个地址空间一样,示意图如下:
虚拟代理:通过虚拟代理来存放实例化需要很长时间的真实对象,最开始创建的是虚拟对象,真正必要的时候再创建真实对象,从而降低系统开销、缩短运行时间。
安全代理:当系统需要控制对真实对象的访问权限;一般用于为不同用户提供不同级别的使用权限。
智能引用代理: 当调用真实的对象时,代理处理另外一些事。比如计算真实对象的引用次数,这样当该对象没有引用时,可以自动释放它;如C++11中的share_ptr智能指针。
参考资料:
http://blog.csdn.net/lovelion/article/details/17517213
http://blog.csdn.net/jiangxinyu/article/details/8528395