(C++设计模式) ------代理模式-- 结构型模式
设计模式的学习是一个循序渐进的过程,每一个设计师都是在套用这几种设计模式来实现自己的软件构架,很多都是融合会贯通的,一个设计模式中不仅仅是用到一种,所以要灵活运用这些设计模式。理解了设计模式对设计和代码的阅读都有很大的好处!!
今天我们学习结构性模式代理(proxy)模式
代理模式:为一个对象提供一种代理机制,用这个代理来控制对这个对象的访问。
有四种常用的情况:
①远程代理 也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实(例如WEBSERVICES)
②虚拟代理 是根据需要创建开销很大的对象。如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。(例如网页中的图片,通过虚拟代理来替代真实的图片,此时代理存储真实图片的路径和尺寸)。
③安全代理 用来控制真实对象访问时的权限
④智能指引 指当调用真实对象时,代理处理另外一些事。
实现要点:
①抽象基类:Subject:定义了Proxy和RealSubject的公有接口。
②两个子类RealSubject类和Proxy类都继承自Subject,这样保证了两个的接口都是一致的。
③Proxy类和RealSuject类关联,Proxy类要保存RealSuject类的一个引用或者指针,以便对实体进行访问。
如图:Client不跟RealSubject交互,而是由Proxy控制对RealSubject的访问。
例子:出处http://blog.csdn.net/wuzhekai1985
考虑一个可以在文档中嵌入图形对象的文档编辑器。有些图形对象的创建开销很大。但是打开文档必须很迅速,因此我们在打开文档时应避免一次性创建所有开销很大的对象。这里就可以运用代理模式,在打开文档时,并不打开图形对象,而是打开图形对象的代理以替代真实的图形。待到真正需要打开图形时,仍由代理负责打开。这是[DP]一书上的给的例子。下面给出代理模式的UML图。
class Image
{
public:
Image(string name): m_imageName(name) {}
virtual ~Image() {}
virtual void Show() {}
protected:
string m_imageName;
};
class BigImage: public Image
{
public:
BigImage(string name):Image(name) {}
~BigImage() {}
void Show() { cout<<"Show big image : "<<m_imageName<<endl; }
};
class BigImageProxy: public Image
{
private:
BigImage *m_bigImage;
public:
BigImageProxy(string name):Image(name),m_bigImage(0) {}
~BigImageProxy() { delete m_bigImage; }
void Show()
{
if(m_bigImage == NULL)
m_bigImage = new BigImage(m_imageName);
m_bigImage->Show();
}
};
客户调用:
int main()
{
Image *image = new BigImageProxy("proxy.jpg"); //代理
image->Show(); //需要时由代理负责打开
delete image;
return 0;
}
与其他相关模式
①适配器模式Adapter :适配器Adapter 为它所适配的对象提供了一个不同的接口。相反,代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,因此,它的接口实际上可能只是实体接口的一个子集。
②装饰器模式Decorator:尽管Decorator的实现部分与代理相似,但 Decorator的目的不一样。Decorator为对象添加一个或多个功能,而代理则控制对对象的访问。