代理(Proxy)模式的浅解

来源:互联网 发布:南京烘焙培训班 知乎 编辑:程序博客网 时间:2024/05/29 19:05

    代理模式就是为其它对象提供一种代理以控制对这个对象的访问。主要解决的问题是:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层, 比如说C和A不在一个服务器上,A要频繁的调用C,我们可以在A上做一个代理类Proxy,把访问C的工作交给Proxy,这样对于A来说,就好像在直接访问C的对象。在对A的开发中我们可以把注意力完全放在业务的实现上。
    一般使用的目的:
如果使用代理模式的目的来划分,代理有以下几种:
  远程代理:为一个对象在不同的地址空间提供局部代表。例如EJB。
  虚拟代理:更具需要开销很大的对象。例如,当我们打开一个网页的时候,文本会很快显示出来,但图片会慢慢显示出来,浏览器对图片的处理就采用了代理模式。
  Copy–on–Write代理:
  保护代理:控制对原始对象的访问。例如:利用代理来访问一些受保护的资源,由代理完成鉴权工作。
  Cache代理:
  防火墙代理:
  同步化代理:
  智能引用代理:
  功能代理:完成某些功能的时候需要一些附加的工作,这时候可以利用代理来进行处理。

  该模式的结构类图如下:

代理模式

为什么要使用Proxy?
1.授权机制 不同级别的用户对同一对象拥有不同的访问权利,如Jive论坛系统中,就使用Proxy进行授权机制控制,访问论坛有两种人:注册用户和游客(未注册用户),Jive中就通过类似ForumProxy这样的代理来控制这两种用户对论坛的访问权限.
2.某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.举例两个具体情况: 
    (1)如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,不能等待大图片处理完成,这时需要做个图片Proxy来代替真正的图片.     上面了除了代码外是我收集的一些代理模式的讲解,我摘抄了还不错的东东,等有新的理解再来修改啊。
    (2)如果那个对象在Internet的某个远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象.

下面上一些代码吧(班长就是帮我们报名的代理)

// ProxyPattern.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <string>#include <iostream>#include <list>using namespace std;class Subject{protected:string mName;public:virtual void request() = 0;};class RealSubject : public Subject{public:RealSubject(){;}RealSubject(string name){mName = name;}void request() {cout << "name:" << mName << " sign up" << endl;;}};//代理类和被代理类都需要派生一个类,我认为是需要他们有同样的接口,以便让代理类来掩饰被代理类的存在?//加个管理List并不是必须的class Proxy : public Subject{private:Subject *m_pSubject;list<Subject*> m_stuList;        //报名的管理列表public:Proxy(){m_pSubject = NULL;};Proxy(Subject* pRealStu):m_pSubject(pRealStu){};//接受一个同学的报名void acceptSignup(Subject *pRealStu){if (pRealStu != NULL){m_stuList.push_back(pRealStu);}}void request(){if (m_pSubject == NULL) {m_pSubject = new RealSubject;}//这里可以增添一些权限控制//......//真实的调用,行使代理功能for(list<Subject*>::iterator i = m_stuList.begin(); i != m_stuList.end(); i++) {(*i)->request();}}};int _tmain(int argc, _TCHAR* argv[]){Subject *stuA = new RealSubject("stuA");Subject *stuB = new RealSubject("stuB");Subject *stuC = new RealSubject("stuC");Proxy *master = new Proxy;master->acceptSignup(stuA);master->acceptSignup(stuB);master->acceptSignup(stuC);master->request();if (stuA != NULL){delete stuA;}if (stuB != NULL){delete stuB;}if (stuC != NULL){delete stuC;}if (master != NULL){delete master;}int temp;cin >> temp;return 0;}
原创粉丝点击