(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为对象添加一个或多个功能,而代理则控制对对象的访问。