【转】设计模式学习笔记(12)-代理

代理模式(Proxy)在设计模式中算是十分重要的了。何谓代理?即客户不是直接访问某个对象而是通过另一对象来达到间接访问的效果。相比直接访问虽然多了一道流程但可以对这个访问过程达到更精细的控制,还是很值得的。

在现实生活中,我们可以使用代理访问网页,广义上的代理包括SSH、VPN等,这些技术都有一个特点,通过别的计算机访问网络,这个计算机称之为代理者。在网站那边,它只知道是代理者访问了自己,而在客户端代理者是透明的,原来在网页上怎么做现在还是怎么做,没有什么变化。唯一不同的是网站可能不认识你了,因为你使用了不同的IP或硬件等。通过代理我们可以做到伪装自己的身份,隐藏个人信息等目的。

在面向对象编程中,我们也是可以使用代理的,毕竟设计模式和现实世界的联系十分紧密。当我们访问一个对象时,直接访问可能不太方便,如:对象是一个远程对象,即对象和对象的应用不在一个堆上;对象可能暂时不可用,如加载对象需要很长的时间;对象只对某些对象开放,想要对权限等作进一步的限制;想要在对对象的访问时作一些附加操作,如实现写时复制(Copy-On-Write)等。在这些情况下,使用代理模式是十分恰当的。

代理模式的类图是十分简单的:

这里有三个类,IObject是一个抽象类,作为接口使用,IObjectImpl是业务相关类,即执行具体操作的实现类,IOjbectProxy是代理类,Client通过这个类来间接访问IObjectImpl。这里写一
下最简单的代理模式:

class IObject 
{
public:
    virtual void operation() = 0;
};
class IObjectImpl : public IObject
{
public:
    void operation()
    {
        cout << "operation by iobjectimpl" << endl; 
    }
};
class IObjectProxy : public IObject
{
private:
    IObject* object;
public:
    IObjectProxy()
    {
        object = new IObjectImpl;
    }
    void operation()
    {
        cout << "before operation" << endl;
        object->operation();
        cout << "after operation" << endl;
    }
};

main方法

IObject* object = new IObjectProxy;
object->operation();

 

这里真实类的operation方法打印operation by iobjectimpl,而在代理类中除了调用真实类中的operation方法外还进行了一些处理操作,如在调用前和调用后各输出了一行字符串。所以最后的输出为:

before operation
operation by iobjectimpl
after operation

 

这就是一个最简单的代理,当然这里我们只是添加了输出字符串的附加操作,根据附加操作的不同Proxy用于:

  • 远程代理
  • 虚代理
  • 保护代理
  • 智能引用

 

远程代理

当本地计算机要访问远程计算机的资源时,可以在本地设置一个Proxy(Java称作skeleton),本地程序访问这个Proxy,这个Proxy在通过与服务器端通信取得执行的结果再返回给本地调用程序
,这就叫做远程代理,Java中的实现称之为RMI。对于本地调用程序来说,它不知道结果是本地产生的还是从远程服务器上下载的,这样就统一的访问接口,简化了操作。

虚代理

当我们做一个客户端,如Android应用程序时,如果要打开某个网页,但这个网页有很多图片,等到所有图片都下载完毕后再打开会消耗很多时间,造成不好的用户体验。一种比较好的方式是通过一个代理对象取得图像,如果图像下载完毕则直接返回这个图像,如果尚未下载完毕则返回一个图像占位符,前台通过轮询的方式访问这个Proxy。当然最好还是用后来要讲的Observer模式,等到图像下载完毕后通知前台程序更新。

保护代理

这没什么好说的,主要是对用户权限的验证。当用户有使用权限时才返回真实的结果,否则返回错误信息。当我们有大量操作需要验证权限时,我们往往会采用一种叫做动态代理的技术,即当用户访问时动态产生代理对象,这样有了一个类就可以对多个对象进行代理,这种编程方法也叫做AOP(面向方面编程)。

智能引用

这是实现写时复制的关键技术,和享元模式类似,当有多个对象读取真实对象时,Proxy对象仅维持一个对该对象的引用,只有当客户对该对象进行操作时才复制一份对象;当所有的引用都取消后,则删除该对象。这种技术可以达到节约空间资源的目的。

Proxy模式主要就适用于以上四种环境,在设计模式中Proxy是十分重要的,日常编程中会经常遇到。

 

 

转自:http://lecoding.com/articles/220.html

posted on 2013-03-05 15:56  TheKingOfKingFish  阅读(123)  评论(0)    收藏  举报

导航