概要
有时候可能我们不希望暴露现有对象的所有接口,只希望公开其中部分接口,具体来说,比如我们有个对象具有一系列的方法接口,如果我们只需要这些接口中间的一小部分,那么我们没必要去创建这个对象本身,我们可以通过一个更轻量的对象作为代理来公开我们需要的那部分接口。
目的
基于需求提供代理对象来实现既有对象接口,可以通过这种模式来调整现有接口的封装。
实例
如概要里面所述的通过代理来暴露部分接口的应用比较简单易懂,这里就不举相关实例来进行说明了。这里举个更典型的Proxy模式的应用方式。
很多应用中经常需要加载图片,视屏等大容量媒体对象,一些第三方库会提供相应的接口,以图片为例,大致接口如下:
class IImage { public: virtual void Show() = 0; }; class HighImage : public IImage { public: HighImage(string path) { LoadImage(path); } void LoadImage(); virtual void Show(); ...... };
HighImage是一个第三方已经提供的支持显示高清图片的对象,在创建这个对象的时候会加载图片,然后Show函数会把已经加载的图片显示出来。
但是在实际使用中却出现了这样的问题,在初始化创建HighImage对象的时候,会加载高清图片,由于高清图片容量比较大,加载需要花费一定时间,目前的需求是希望在初始化创建过程中不要去花费时间加载图片,而是在需要显示的时候才去加载并显示出来。
Proxy模式该登场了。让我们通过Proxy代理对象来解决上面的问题。新建一个HighImageProxy类(备注:代码中对象怎么销毁不在考虑范畴)。
class HighImageProxy { public: HighImageProxy(string path) { mPath = path; } virtual void Show() { mImage = new HighImage(mPath); mImage->Show(); } private: HighImage* mImage; string mPath; };
HighImageProxy类代理了HighImage的基本行为,但是它在创建对象时并不加载图片,而是在Show方法里进行加载。对Client端而言,在创建HighImageProxy对象时不需要花费图片加载的时间,满足了我们的需求。
应用
一些安全代理中经常会限制对象的访问权限,很多都是通过Proxy模式来实现的。如上面实例的Proxy模式应用也是非常常见的一种。另外也要注意Proxy模式和Adapter模式的区别,Adapter模式是会改变接口调用形式来进行适配的,而Proxy模式则是不会改变现有接口形式,使用相同的接口调用方式。