Proxy模式真心是一个比较精巧的模式, 尤其通过C++重载运算符(& ->),让你瞬间对C++的感情重归于好,忘记它的库或者框架的缺乏之痛苦.(另外一个令其他高级语言目瞪的是重载new/delete,来管理大块内存). 对于Proxy本身来说, 它还是涵盖了多种模型,比如Remote Proxy, Virtual Proxy, Protection Proxy, and Smart Reference Proxy, 尤其后者,对于编程技巧要求是比较高的.
评价: Proxy,属于战斗精英级别, 在程序大规模应用的场景不如Strategy这些行为模式,但是其理念还是处于OOP的核心价值,所以非常重要.
区别,Adapter的目标于接口转接,Decorator目标于接口的额外扩展, 而Proxy目标于对象代理,带来额外的功能,比如远程访问,虚拟缓存,权限代理,和引用技术生命周期管理等.
上纯手打程序:
// Proxy.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
//------- Remote Proxy-------------------
class ClientWebService
{
public:
void Login(){ cout << " Login to remove service." << endl;}
void Logout() { cout << " logout. " <<endl;}
};
class RemoteProxy
{
ClientWebService _remote;
public:
RemoteProxy(){ cout << "connecting.." << endl;}
~RemoteProxy(){ cout << "disconnectingg.." << endl;}
void Login(){
_remote.Login();
}
void Logout(){
_remote.Logout();
}
};
//------- Virtual Proxy-------------------
class Image
{
public:
static Image* LoadImage(){ cout << "Load Image from Disk." << endl; return new Image(); }
void Display(){}
};
class VirtualProxy
{
Image* _image;
public:
void Display(){
_image = Image::LoadImage();
_image->Display();
}
};
//------- Protection Proxy-------------------
class RealObject
{
public:
void Method(){ cout << "Real object called." << endl; }
};
class ProtectionProxy
{
RealObject _real;
public:
void Method(char* user){
cout << "this object is allowed by " << user << endl;
_real.Method();
}
};
//-------Smart Reference Proxy for preexisint class -----------------
class ReferenceCounting
{
int _ref;
public:
ReferenceCounting(): _ref(1){}
int add(){ cout << " add ref = " << _ref+1 << endl; return ++_ref; }
int reduce(){ cout << " reduce ref = " << _ref-1 << endl; return --_ref; }
};
template<class T>
class auto_ptr
{
T* _p;
ReferenceCounting* _ref;
public:
auto_ptr(T* p):_p(p), _ref(new ReferenceCounting()) {}
~auto_ptr(){
int ref = _ref->reduce();
if(ref == 0){
delete _p;
delete _ref;
}
}
auto_ptr(const auto_ptr& copy): _p(copy._p), _ref(copy._ref) {
_ref->add();
}
T* operator->(){ return _p;}
T& operator&(){ return *_p;}
auto_ptr& operator=(const auto_ptr& copy){
if(this != ©){
if(_ref){
if( 0 == _ref->reduce() )
delete _p;
}
_p = copy._p;
_ref = copy._ref;
_ref->add();
}
return *this;
}
};
/*
* Note: for smart pointer, there is still concurent access, this need synchoronized lock.
* multiple reference usage to improve by inherit from reference counting class.
*/
//
int main(int argc, char* argv[])
{
RemoteProxy remote;
remote.Login();
VirtualProxy imagePxy;
imagePxy.Display();
ProtectionProxy protect;
protect.Method("Jinbao");
/// Cant proxy twice or more.
RemoteProxy* pRemote = new RemoteProxy();
auto_ptr<RemoteProxy> ap(pRemote);
ap->Login();
auto_ptr<RemoteProxy> app = ap;
app->Logout();
auto_ptr<RemoteProxy> appp(new RemoteProxy());
appp = app;
return 0;
}