The Proxy design pattern provides a surrogate or placeholder for another object to control access to it.
C# code examples of the Proxy design pattern is provided in 3 forms:
A visualization of the classes and objects participating in this pattern.
The classes and objects participating in this pattern include:
MathProxy
)
IMath
)
Math
)
This structural code demonstrates the Proxy pattern which provides a representative object (proxy) that controls access to another similar object.
using System;
namespace Proxy.Structural
{
/// <summary>
/// Proxy Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
// Create proxy and request a service
Proxy proxy = new Proxy();
proxy.Request();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Subject' abstract class
/// </summary>
public abstract class Subject
{
public abstract void Request();
}
/// <summary>
/// The 'RealSubject' class
/// </summary>
public class RealSubject : Subject
{
public override void Request()
{
Console.WriteLine("Called RealSubject.Request()");
}
}
/// <summary>
/// The 'Proxy' class
/// </summary>
public class Proxy : Subject
{
private RealSubject realSubject;
public override void Request()
{
// Use 'lazy initialization'
if (realSubject == null)
{
realSubject = new RealSubject();
}
realSubject.Request();
}
}
}
This real-world code demonstrates the Proxy pattern for a Math object represented by a MathProxy object.
using System;
namespace Proxy.RealWorld
{
/// <summary>
/// Proxy Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
// 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>
public 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>
public 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);
}
}
}
The .NET optimized code demonstrates the same code as above but uses
more modern C# and .NET features.
Here is an elegant C# Proxy solution.
namespace Proxy.NetOptimized;
using static System.Console;
using System.Threading;
/// <summary>
/// Proxy Design Pattern
/// </summary>
public class Program
{
public static void Main()
{
// Create math proxy
var proxy = new MathProxy();
// Do the math
WriteLine($"4 + 2 = {proxy.Add(4, 2)}");
WriteLine($"4 - 2 = {proxy.Sub(4, 2)}");
WriteLine($"4 * 2 = {proxy.Mul(4, 2)}");
WriteLine($"4 / 2 = {proxy.Div(4, 2)}");
// Wait for user
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>
public class Math : IMath
{
public double Add(double x, double y) => x + y;
public double Sub(double x, double y) => x - y;
public double Mul(double x, double y) => x * y;
public double Div(double x, double y) => x / y;
}
/// <summary>
/// The remote 'Proxy Object' class
/// </summary>
public class MathProxy : IMath
{
private readonly Math math = new();
public double Add(double x, double y)
{
Thread.Sleep(800);
return math.Add(x, y);
}
public double Sub(double x, double y)
{
Thread.Sleep(800);
return math.Sub(x, y);
}
public double Mul(double x, double y)
{
Thread.Sleep(800);
return math.Mul(x, y);
}
public double Div(double x, double y)
{
Thread.Sleep(800);
return math.Div(x, y);
}
}