Wednesday, 13 October 2010

C++ example of Proxy Design Pattern

The Proxy pattern is used when you need to represent a complex object by a simpler one. If creating an object is expensive in time or computer resources, Proxy allows you to postpone this creation until you need the actual object. A Proxy usually has the same methods as the object it represents, and once the object is loaded, it passes on the method calls from the Proxy to the actual object.

There are several cases where a Proxy can be useful:

1. If an object, such as a large image, takes a long time to load.
2. If the object is on a remote machine and loading it over the network may be slow, especially during peak network load periods.
3. If the object has limited access rights, the proxy can validate the access permissions for that user.

Proxies can also be used to distinguish between requesting an instance of an object and the actual need to access it. For example, program initialization may set up a number of objects which may not all be used right away. In that case, the proxy can load the real object only when it is needed.


The Proxy provides a surrogate or place holder to provide access to an object. A check or bank draft is a proxy for funds in an account. A check can be used in place of cash for making purchases and ultimately controls access to cash in the issuer’s account.



The frequency of use of Proxy is medium high

Lets look at the example below. Note that the actual Math class is created in the MathProxy when math operations need to be performed.



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Proxy is part of Structural Patterns
//Structural Patterns deal with decoupling the interface and implementation of classes and objects
//A Proxy provides a surrogate or placeholder for another object to control access to it.

//The example we consider here a math class
//The proxy provides an interface but the real class is only initiated when it is used

#include<iostream>
#include<string>

using namespace
std;


// The 'Subject interface
class IMath
{

public
:
virtual
double Add(double x, double y) = 0;
virtual
double Sub(double x, double y) = 0;
virtual
double Mul(double x, double y) = 0;
virtual
double Div(double x, double y) = 0;
};


// The 'RealSubject' class
class Math : public IMath
{

public
:
double
Add(double x, double y)
{

return
x + y;
}

double
Sub(double x, double y)
{

return
x - y;
}

double
Mul(double x, double y)
{

return
x * y;
}

double
Div(double x, double y)
{

return
x / y;
}
};


// The 'Proxy Object' class
class MathProxy : public IMath
{

public
:
MathProxy()
{

math_ = NULL;
}

virtual
~MathProxy()
{

if
(math_)
delete
math_;
}

double
Add(double x, double y)
{

return
getMathInstance()->Add(x, y);
}

double
Sub(double x, double y)
{

return
getMathInstance()->Sub(x, y);
}

double
Mul(double x, double y)
{

return
getMathInstance()->Mul(x, y);
}

double
Div(double x, double y)
{

return
getMathInstance()->Div(x, y);
}

private
:
Math* math_;
Math* getMathInstance(void)
{

if
(!math_)
math_ = new Math();
return
math_;
}
};


//The Main method
int main()
{

// Create math proxy
MathProxy proxy;

//Do the math
cout<<"4 + 2 = "<<proxy.Add(4, 2)<<endl;
cout<<"4 - 2 = "<<proxy.Sub(4, 2)<<endl;
cout<<"4 * 2 = "<<proxy.Mul(4, 2)<<endl;
cout<<"4 / 2 = "<<proxy.Div(4, 2)<<endl;

return
0;
}



The output is as follows:



For more information see:

http://sourcemaking.com/design_patterns/proxy

http://www.patterndepot.com/put/8/proxy.pdf

http://www.dofactory.com/Patterns/PatternProxy.aspx

5 comments:

  1. I have a doubt. Once the real object is created, total memory requirement is equivalent to the implementation without proxy pattern.(actually little bit more because of proxy and interface class objects).

    ReplyDelete
  2. Great Explanation. Another great article i recommend is this one

    ReplyDelete
  3. Nice, clear explanation, thanks!

    ReplyDelete