Proxy - shoonie/StudyingDesignPattern GitHub Wiki
Provide a surrogate or placeholder for another object to control access to it.
The Proxy pattern introduces a level of indirection when accessing an object. The additional indirection has many uses, depending on the kind of proxy.
- A remote proxy can hide the fact that an object resides in a different address space.
- A virtual proxy can perform optimizations such as creating an object on demand.
- Both protection proxies and smart references allow additional housekeeping tasks when an object is accessed.
- Overloading the member access operator in C++ (operator -> and * operator)
class Image;
extern Image* LoadAndImageFile(const char*);
//external function
class ImagePtr
{
public:
ImagePtr(const char* imageFile);
virtual ~ImagePtr();
virtual Image* operator->();
virtual Image& operator*();
private:
Image * LoadImage();
private:
Image * _image;
const char* _imageFile;
};
ImagePtr::ImagePtr(const char* imageFile)
{
_imageFile = imageFile;
_image = nullptr;
}
ImagePtr::~ImagePtr()
{
if (_image != nullptr)
delete _image;
}
Image* ImagePtr::LoadImage()
{
if (_image == nullptr)
{
_image = LoadAndImageFile(_imageFile);
}
return _image;
}
// overload -> and * operator use LoadImage to return _image to caller(loading if necessary)
Image* ImagePtr::operator->()
{
return LoadImage();
}
Image& ImagePtr::operator*()
{
return *LoadImage();
}
// This approach lets you call Image operations through ImagePtr objects without
// going to the trouble of making the opertation part of the ImagePtr interface:
ImagePtr image = ImagePtr("anImageFilename");
image->Draw(Point(50,100));
//(image.operator->())->Draw(Point(50,100));
// Notice how the image proxy acts like a pointer, but it's not declared to be a pointer to an Image.
// That means you can't use it exactly like a real pointer to an Image. Hence clients must treat Image and
// ImagePtr objects differently in this approach.
- Proxy doesn't always have to know the type of real subject. If a Proxy class can deal with its subject solely through an abstract interface, then there's no need to make a Proxy class for each RealSubject class; the proxy can deal with all Realsubject classes uniformly.
#include<iostream>
#include<string>
using namespace std;
class IBank
{
public:
virtual string WithDrawCash(void) = 0;
virtual ~IBank() {}
};
class ActualBank : IBank
{
public:
string WithDrawCash(void)
{
return "Here, have a million Zimbabwean dollars.\n\n";
}
};
class Bank : public IBank
{
ActualBank* _bank;
string _password;
public:
Bank() :_bank(nullptr), _password("WhoWhatWhere") {}
string WithDrawCash(void)
{
if (_bank == nullptr)
return "\nDid you authenticate?\n";
return _bank->WithDrawCash();
}
void Authenticate(string passwd)
{
if (_password == passwd)
{
cout << "\nYou have been authenticated.\n\n";
_bank = new ActualBank();
}
else
{
cout << "\nSorry but wrong.\n";
}
}
~Bank()
{
if(_bank!=nullptr)
delete _bank;
}
};
int main()
{
Bank* daddysBank = new Bank();
cout << daddysBank->WithDrawCash();
daddysBank->Authenticate("Hello");
daddysBank->Authenticate("WhoWhatWhere");
cout << daddysBank->WithDrawCash();
return 1;
}