天天看点

Proxy模式

                    Proxy模式是 构造型的设计模式之一. 所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。   根据这些“特别处理”的不同, 有以下几种常见的代理模式:

- Remote proxy:远程代理。该代理可以让客户端透明地引用一个存在于不同地址空间(远程或本地)的对象。

-   Virtual proxy:虚拟代理。该代理允许一个对象只有在真正被用到时才被创建。

-   Copy-on-write proxy:对象拷贝延迟代理。该代理可以延迟一个对象的拷贝(clone)操作到客户调用里,它是virtual proxy模式的一种特殊情况。一般来说,对象的深度克隆是一个高开销的动作,该代理可以让这个动作延迟,只有对象被用到的时候才被克隆。

- Protection (access) proxy:访问保护代理。该代理可以在访问一个对象时附加一些检查操作,比如权限验证等。

- Cache proxy:缓存代理。主要为那些创建时高开销的对象提供缓存,以供多客户端共享。

-   Firewall proxy:防火墙代理。保护目标对象不受某些不良客户端的侵害。

-   Synchronization proxy:为非同步的目标对象提供并发控制。

- Smart reference proxy:当一个对象被引用时提供某些额外的操作。比如对象被引用时,记录对象被引用的次数等。 ========================================================================================================== 上面对proxy模式的阐述来自网络 下面是我对 Protection (access) proxy的一个实现。

Proxy模式

  #ifndef FILEOPERATOR_H

#define FILEOPERATOR_H      
#include <iostream>      
using namespace std;      
class FileOperator      
{      
public:      
enum  permission {READ ,ALL};      
FileOperator();      
FileOperator(permission _p);      
virtual ~FileOperator() = 0;      
virtual string getFileName()const = 0;      
virtual int getLength() const = 0;      
virtual string modify(string context) = 0;      
protected:      
permission getPermission() const {return p;}      
private:      
permission p;      
};      
#endif // FILEOPERATOR_H      
#include "fileoperator.h"           
FileOperator::FileOperator(permission _p):p(_p)      
{      
}      
FileOperator::FileOperator()      
{      
p = FileOperator::READ;      
}      
FileOperator::~FileOperator()      
{      
}      
#ifndef PROXYFILEOPERATOR_H       
#define PROXYFILEOPERATOR_H      
#include "fileoperator.h"      
#include "realfileoperator.h"      
class ProxyFileOperator: public FileOperator      
{      
public:      
ProxyFileOperator(string _name);      
ProxyFileOperator(string _name,permission _p);      
~ProxyFileOperator(){delete real;}      
string getFileName() const{return real->getFileName();}      
int getLength()const {return real->getLength();}      
string modify(string context) {return real->modify(context);}      
private:      
RealFileOperator *real;      
};      
#endif // PROXYFILEOPERATOR_H      
#include "proxyfileoperator.h"           
ProxyFileOperator::ProxyFileOperator(string _name, permission _p):FileOperator(_p)      
{      
real = new RealFileOperator(_name,getPermission());      
}      
ProxyFileOperator::ProxyFileOperator(string _name):FileOperator()      
{      
real = new RealFileOperator(_name);      
}      
#ifndef REALFILEOPERATOR_H       
#define REALFILEOPERATOR_H      
#include "fileoperator.h"      
class RealFileOperator : public FileOperator      
{      
public:      
RealFileOperator(string _name);      
RealFileOperator(string _name,permission _P);      
~RealFileOperator(){}      
string getFileName()const {return fileName;}      
int getLength()const {return fileName.length();}      
string modify(string context);      
private:      
string fileName;      
};      
#endif // REALFILEOPERATOR_H      
#include "realfileoperator.h"           
RealFileOperator::RealFileOperator(string _name, permission _P):FileOperator(_P),fileName(_name)      
{      
}      
RealFileOperator::RealFileOperator(string _name):FileOperator(),fileName(_name)      
{      
}      
string RealFileOperator::modify(string context)      
{      
if(getPermission() == FileOperator::ALL) {      
fileName += context;      
return "ok";      
}      
else {      
return "no";      
}      
}      
#include <iostream>           
using namespace std;      
#include "proxyfileoperator.h"      
int main()      
{      
FileOperator *p = new ProxyFileOperator("I am zhou xiang!");      
cout << p->getFileName()<<'\n';      
if (p->modify("Love ChenChen!\n") == "ok") {      
cout << p->getFileName();      
}      
else {      
cout<<"ERROR Permission denied!";      
}      
delete p;      
return 0;      
}      
默认只有读的权限,输出为
        
Proxy模式
修给之后, FileOperator *p = new ProxyFileOperator("I am zhou xiang!",FileOperator::ALL);      
输出结果,
        
Proxy模式
====================================================================================================      
Proxy模式在访问对象时引入了一定程度的间接性。根据代理的类型,附加的间接性有多种用途: 1) Remote Proxy可以隐藏一个对象存在于不同地址空间的事实。也使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。 2) Virtual Proxy 可以进行最优化,例如根据要求创建对象。即通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗。 3) Protection Proxies和Smart Reference都允许在访问一个对象时有一些附加的内务处理(Housekeeping task) 。 Proxy模式还可以对用户隐藏另一种称之为写时复制(copy-on-write)的优化方式,该优化与根据需要创建对象有关。拷贝一个庞大而复杂的对象是一种开销很大的操作,如果这个拷贝根本没有被修改,那么这些开销就没有必要。用代理延迟这一拷贝过程,我们可以保证只有当这个对象被修改的时候才对它进行拷贝。在实现copy-on-write时必须对实体进行引用计数。拷贝代理仅会增加引用计数。只有当用户请求一个修改该实体的操作时,代理才会真正的拷贝它。在这种情况下,代理还必须减 少实体的引用计数。当引用的数目为零时,这个实体将被删除。copy-on-write可以大幅度的降低拷贝庞大实体时的开销。 代理模式能够 协调调用者和被调用者 ,在一定程度上降低了系统的耦合度。 代理模式的缺点 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

继续阅读