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的一个实现。

#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可以大幅度的降低拷贝庞大实体时的开销。 代理模式能够 协调调用者和被调用者 ,在一定程度上降低了系统的耦合度。 代理模式的缺点 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。