代理模式(Proxy)的目标是为其他对象提供一个代理或地方以控制对这个对象的访问。当客户向代理对象第一次提出请求时,代理实例化真实对象,并且将请求传给它,以后所有客户请求都经由代理传给真实对象。代理模式分为4类:
1、虚拟代理(Virtual Proxy):直到首次请求时才生成一个真实的耗费代理,它用来存放花费大的真实对象。
2、远程代理(Remote Proxy):本地的代理对象控制一个远程对象。
3、安全代理(Protection Proxy):代理检查调用真实对象所需要的权限。
4、聪明引用(Smart Reference):当调用真实对象时,代理处理另外一些事情。
其结构图如下:
以一个简单的数学计算程序为例,这个程序只负责进行简单的加减乘除运算,但这个程序部署在一台服务器上,与客户程序不在同一个地址空间之内,调用该程序时要考虑网络的问题,对接收到的结果解包等一系列操作,这时就可以用一个本地代理来代替该程序处理一切的网络问题。结构图如下:
实现代码:
//IMath.h
class IMath
{
public:
IMath();
virtual ~IMath();
virtual double Add(double, double) = 0;
virtual double Sub(double, double) = 0;
virtual double Mul(double, double) = 0;
virtual double Dev(double, double) = 0;
};
//IMath.cpp
#include "stdafx.h"
#include "IMath.h"
IMath::IMath()
{
}
IMath::~IMath()
{
}
//Math.h
#include "IMath.h"
class Math : public IMath
{
public:
Math();
virtual ~Math();
double Add(double, double);
double Sub(double, double);
double Mul(double, double);
double Dev(double, double);
};
//Math.cpp
#include "stdafx.h"
#include "Math.h"
Math::Math()
{
}
Math::~Math()
{
}
double Math::Add(double x, double y)
{
return x + y;
}
double Math::Sub(double x, double y)
{
return x - y;
}
double Math::Mul(double x, double y)
{
return x * y;
}
double Math::Dev(double x, double y)
{
return x / y;
}
//MathProxy.h
#include "IMath.h"
class Math;
class MathProxy : public IMath
{
public:
MathProxy();
virtual ~MathProxy();
double Add(double, double);
double Sub(double, double);
double Mul(double, double);
double Dev(double, double);
private:
Math* m_pMath;
};
//MathProxy.cpp
#include "stdafx.h"
#include "MathProxy.h"
#include "Math.h"
MathProxy::MathProxy()
{
m_pMath = new Math;
}
MathProxy::~MathProxy()
{
if(m_pMath != NULL)
{
delete m_pMath;
m_pMath = NULL;
}
}
double MathProxy::Add(double x, double y)
{
return m_pMath->Add(x, y);
}
double MathProxy::Sub(double x, double y)
{
return m_pMath->Sub(x, y);
}
double MathProxy::Mul(double x, double y)
{
return m_pMath->Mul(x, y);
}
double MathProxy::Dev(double x, double y)
{
return m_pMath->Dev(x, y);
}
//main.cpp
#include "stdafx.h"
#include "IMath.h"
#include "MathProxy.h"
int main(int argc, char* argv[])
{
IMath* pMath = new MathProxy;
double result = pMath->Add(8.5, 5.1);
printf("%f\n", result);
return 0;
}
代理模式、装饰模式与适配器模式有点类似,都是通过中间层来实现原有对象功能,但它们解决问题的目标不同,其区别为:
代理模式只是原来对象的一个替身(原来对象约束了代理的行为)。
装饰模式是对原对象的功能增强。
适配器模式是要改变原对象的接口。