Definition
|
Provide a surrogate or placeholder for another object to control access to it. |
UML class diagram Participants
|
The classes and/or objects participating in the Proxy 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.
|
Sample code in C#
This structural code demonstrates the Proxy pattern which provides a representative object (proxy) that controls access to another similar object.
// Proxy pattern -- Structural example |
using System;
// "Subject"
abstract class Subject
{
// Methods
abstract public void Request();
}
// "RealSubject"
class RealSubject : Subject
{
// Methods
override public void Request()
{
Console.WriteLine("Called RealSubject.Request()");
}
}
// "Proxy"
class Proxy : Subject
{
// Fields
RealSubject realSubject;
// Methods
override public void Request()
{
// Uses "lazy initialization"
if( realSubject == null )
realSubject = new RealSubject();
realSubject.Request();
}
}
/// <summary>
/// Client test
/// </summary>
public class Client
{
public static void Main( string[] args )
{
// Create proxy and request a service
Proxy p = new Proxy();
p.Request();
}
} |
This real-world code demonstrates the Remote Proxy pattern which provides a representative object that controls access to another object in a different AppDomain.
// Proxy pattern -- Real World example |
using System;
using System.Runtime.Remoting;
// "Subject"
public interface IMath
{
// Methods
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 : MarshalByRefObject, IMath
{
// Methods
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; }
}
// Remote "Proxy Object"
class MathProxy : IMath
{
// Fields
Math math;
// Constructors
public MathProxy()
{
// Create Math instance in a different AppDomain
AppDomain ad = System.AppDomain.CreateDomain( "MathDomain",null, null );
ObjectHandle o = ad.CreateInstance("Proxy_RealWorld", "Math", false,
System.Reflection.BindingFlags.CreateInstance, null, null, null,null,null );
math = (Math) o.Unwrap();
}
// Methods
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);
}
}
/// <summary>
/// ProxyApp test
/// </summary>
public class ProxyApp
{
public static void Main( string[] args )
{
// Create math proxy
MathProxy p = new MathProxy();
// Do the math
Console.WriteLine( "4 + 2 = {0}", p.Add( 4, 2 ) );
Console.WriteLine( "4 - 2 = {0}", p.Sub( 4, 2 ) );
Console.WriteLine( "4 * 2 = {0}", p.Mul( 4, 2 ) );
Console.WriteLine( "4 / 2 = {0}", p.Div( 4, 2 ) );
}
} |