 |
Provide a surrogate or placeholder for another object to control access to it.
Frequency of use: medium high
|
|
 |
The classes and/or objects participating in this pattern are:
- Proxy (MathProxy)
- maintains a reference that lets the proxy access the real subject. Proxy may
refer to a Subject if the RealSubject and Subject interfaces are the same.
- provides an interface identical to Subject's so that a proxy can be
substituted for for the real subject.
- controls access to the real subject and may be responsible for creating and
deleting it.
- other responsibilites depend on the kind of proxy:
- remote proxies are responsible for encoding a request and its
arguments and for sending the encoded request to the real subject in a different
address space.
- virtual proxies may cache additional information about the real
subject so that they can postpone accessing it. For example, the ImageProxy from
the Motivation caches the real images's extent.
- protection proxies check that the caller has the access permissions
required to perform a request.
- Subject (IMath)
- defines the common interface for RealSubject and Proxy so that a Proxy can
be used anywhere a RealSubject is expected.
- RealSubject (Math)
- defines the real object that the proxy represents.
This structural code demonstrates the Proxy pattern which provides a representative object (proxy)
that controls access to another similar object.
Show code
|
// Proxy pattern -- Structural example
|
|
using System;
namespace DoFactory.GangOfFour.Proxy.Structural
{
// MainApp test application
class MainApp
{
static void Main()
{
// Create proxy and request a service
Proxy proxy = new Proxy();
proxy.Request();
// Wait for user
Console.Read();
}
}
// "Subject"
abstract class Subject
{
public abstract void Request();
}
// "RealSubject"
class RealSubject : Subject
{
public override void Request()
{
Console.WriteLine("Called RealSubject.Request()");
}
}
// "Proxy"
class Proxy : Subject
{
RealSubject realSubject;
public override void Request()
{
// Use 'lazy initialization'
if (realSubject == null)
{
realSubject = new RealSubject();
}
realSubject.Request();
}
}
}
|
Output
Called RealSubject.Request()
|
This real-world code demonstrates the Proxy pattern
for a Math object represented by a MathProxy object.
Show code
|
// Proxy pattern -- Real World example
|
|
using System;
namespace DoFactory.GangOfFour.Proxy.RealWorld
{
// Mainapp test application
class MainApp
{
static void Main()
{
// Create math proxy
MathProxy p = new MathProxy();
// Do the math
Console.WriteLine("4 + 2 = " + p.Add(4, 2));
Console.WriteLine("4 - 2 = " + p.Sub(4, 2));
Console.WriteLine("4 * 2 = " + p.Mul(4, 2));
Console.WriteLine("4 / 2 = " + p.Div(4, 2));
// Wait for user
Console.Read();
}
}
// "Subject"
public interface IMath
{
double Add(double x, double y);
double Sub(double x, double y);
double Mul(double x, double y);
double Div(double x, double y);
}
// "RealSubject"
class Math : IMath
{
public double Add(double x, double y){return x + y;}
public double Sub(double x, double y){return x - y;}
public double Mul(double x, double y){return x * y;}
public double Div(double x, double y){return x / y;}
}
// "Proxy Object"
class MathProxy : IMath
{
Math math;
public MathProxy()
{
math = new Math();
}
public double Add(double x, double y)
{
return math.Add(x,y);
}
public double Sub(double x, double y)
{
return math.Sub(x,y);
}
public double Mul(double x, double y)
{
return math.Mul(x,y);
}
public double Div(double x, double y)
{
return math.Div(x,y);
}
}
}
|
Output
4 + 2 = 6
4 - 2 = 2
4 * 2 = 8
4 / 2 = 2
|
This .NET optimized code demonstrates the
same real-world situation as above but uses modern, built-in .NET features.
Show code
|
// Proxy pattern -- .NET optimized
|
See our Singleton page for a .NET optimized code sample.
|
|
|