代理模式(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;
}
代理模式、裝飾模式與適配器模式有點類似,都是通過中間層來實現原有對象功能,但它們解決問題的目標不同,其區別為:
代理模式只是原來對象的一個替身(原來對象約束了代理的行為)。
裝飾模式是對原對象的功能增強。
適配器模式是要改變原對象的接口。