一、模式动机
在某些情况下,一个客户不想或者不能直接引用一个对 象,此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到 中介的作用,并且可以通过代理对象去掉客户不能看到 的内容和服务或者添加客户需要的额外服务。
二、模式定义
代理模式(Proxy Pattern):为另一个对象提供一个替身或占位符以控制对这个对象的访问。
代理模式包含如下角色:
- Subject: 抽象主题角色
- Proxy: 代理主题角色
RealSubject: 真实主题角色
三、模式示例
利用虚拟代理(Virtual Proxy)显示CD封面。建立一个应用程序,用来展现CD封面,建立时从Amazon.com等网站的在线服务中下载CD封面的图片。在等待CD封面加载的时候,显示“CD封面加载中,请稍候…”。
C++代码实现
#include "windows.h"
#include "iostream"
#include "thread"
using namespace std;
//Subject类
class Icon
{
public:
virtual void paintIcon() = 0;
};
//RealSubject类
class ImageIcon : public Icon
{
public:
void paintIcon()
{
cout << "绘制CD封面" << endl;
}
};
//Proxy类
class ImageProxy : public Icon
{
public:
void paintIcon()
{
if (imageIcon != nullptr)
{
imageIcon->paintIcon();
}
else
{
cout << "CD封面加载中,请稍候..." << endl;
thread T1(ImageProxy::LoadIcon, this);
T1.detach();
}
}
static void LoadIcon(ImageProxy *proxy)
{
Sleep(2000); //假设下载所需时间
proxy->imageIcon = new ImageIcon();
proxy->imageIcon->paintIcon();
}
private:
ImageIcon* imageIcon = nullptr;
};
int _tmain(int argc, _TCHAR* argv[])
{
Icon* icon = new ImageProxy();
icon->paintIcon();
cout << "主线程继续" << endl;
Sleep(2000);
system("pause");
return 0;
}
运行结果:
四、分析总结
使用代理模式创建代表对象,让代表对象控制某对象的访问。怎么理解“控制访问”?远程代理控制访问,管理客户和远程对象之间的交互。虚拟代理控制访问,实例化开销大的对象。虚拟代理经常直到我们真正需要一个对象的时候才创建它。 保护代理控制访问,基于调用者控制对象方法的访问。
优点
- 代理模式能够协调调用者和被调用者,在一定程度上降低了系 统的耦合度。
- 远程代理使得客户端可以访问在远程机器上的对象,远程机器 可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
- 虚拟代理通过使用一个小对象来代表一个大对象,可以减少系 统资源的消耗,对系统进行优化并提高运行速度。
- 保护代理可以控制对真实对象的使用权限。
缺点
- 由于在客户端和真实主题之间增加了代理对象,因此 有些类型的代理模式可能会造成请求的处理速度变慢。
- 实现代理模式需要额外的工作,有些代理模式的实现 非常复杂。