.NET Design Patterns

Proxy


 Definition
 UML diagram
 Participants
 Structural code in C#
 Real-world code in C#
 .NET Optimized code in C#



Definition

Provide a surrogate or placeholder for another object to control access to it.

Frequency of use:
Medium high




UML class diagram






Participants


    The classes and 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.



Structural code in C#


This structural code demonstrates the Proxy pattern which provides a representative object (proxy) that controls access to another similar object.

                 

using System;

 

namespace DoFactory.GangOfFour.Proxy.Structural

{

  /// <summary>

  /// MainApp startup class for Structural

  /// Proxy Design Pattern.

  /// </summary>

  class MainApp

  {

    /// <summary>

    /// Entry point into console application.

    /// </summary>

    static void Main()

    {

      // Create proxy and request a service

      Proxy proxy = new Proxy();

      proxy.Request();

 

      // Wait for user

      Console.ReadKey();

    }

  }

 

  /// <summary>

  /// The 'Subject' abstract class

  /// </summary>

  abstract class Subject

  {

    public abstract void Request();

  }

 

  /// <summary>

  /// The 'RealSubject' class

  /// </summary>

  class RealSubject : Subject

  {

    public override void Request()

    {

      Console.WriteLine("Called RealSubject.Request()");

    }

  }

 

  /// <summary>

  /// The 'Proxy' class

  /// </summary>

  class Proxy : Subject

  {

    private RealSubject _realSubject;

 

    public override void Request()

    {

      // Use 'lazy initialization'

      if (_realSubject == null)

      {

        _realSubject = new RealSubject();

      }

 

      _realSubject.Request();

    }

  }

}


Output
Called RealSubject.Request()




Real-world code in C#


This real-world code demonstrates the Proxy pattern for a Math object represented by a MathProxy object.

                 

using System;

 

namespace DoFactory.GangOfFour.Proxy.RealWorld

{

  /// <summary>

  /// MainApp startup class for Real-World

  /// Proxy Design Pattern.

  /// </summary>

  class MainApp

  {

    /// <summary>

    /// Entry point into console application.

    /// </summary>

    static void Main()

    {

      // Create math proxy

      MathProxy proxy = new MathProxy();

 

      // Do the math

      Console.WriteLine("4 + 2 = " + proxy.Add(4, 2));

      Console.WriteLine("4 - 2 = " + proxy.Sub(4, 2));

      Console.WriteLine("4 * 2 = " + proxy.Mul(4, 2));

      Console.WriteLine("4 / 2 = " + proxy.Div(4, 2));

 

      // Wait for user

      Console.ReadKey();

    }

  }

 

  /// <summary>

  /// The 'Subject interface

  /// </summary>

  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);

  }

 

  /// <summary>

  /// The 'RealSubject' class

  /// </summary>

  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; }

  }

 

  /// <summary>

  /// The 'Proxy Object' class

  /// </summary>

  class MathProxy : IMath

  {

    private Math _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




.NET Optimized code in C#


The .NET optimized code demonstrates the same real-world situation as above but uses modern, built-in .NET features, such as, generics, reflection, object initializers, automatic properties, etc. You can find an example on our Singleton pattern page.

All other patterns (and much more) are available in our .NET Design Pattern Framework 4.5.


Not only does the .NET Design Pattern Framework 4.5 cover GOF and Enterprise patterns, it also includes .NET pattern architectures that reduce the code you need to write by up to 75%. This unique package will change your .NET lifestyle -- for only $79.  Here's what is included:



  • 69 gang-of-four pattern projects
  • 46 head-first pattern projects
  • Fowler's enterprise patterns
  • Multi-tier patterns
  • Convention over configuration
  • Active Record and CQRS patterns
  • Repository and Unit-of-Work patterns
  • MVC, MVP, & MVVM patterns
  • REST patterns with Web API
  • SparkTM Rapid App Dev (RAD) platform!
  • Art Shop MVC Reference Application
  • 100% pure source code