This is part of a series of posts demonstrating software design patterns using C# and .NET. The patterns are taken from the book Design Patterns by the Gang of Four. Here's the series index page.

What Is This Pattern?

The Proxy pattern provides a surrogate or placeholder object to control access to another, different object. The Proxy object can be used in the same manner as its containing object.

The Proxy object can then hide or change data on the hidden object, or otherwise manipulate its behavior. However, the Proxy must still be able to be used anywhere the hidden object is.

The Rundown

  • Type: Structural
  • Useful? 4/5 (Very)
  • Good For: Controlling access to a particular object, testing scenarios.
  • Example Code: On GitHub

The Participants

  • The Subject defines a common interface for the RealSubject and the Proxy such that the Proxy can be used anywhere the RealSubject is expected.
  • The RealSubject defines the concrete object which the Proxy represents.
  • The Proxy maintains a reference to the RealSubject and controls access to it. It must implement the same interface as the RealSubject so that the two can be used interchangeably.

A Delicious Example

To demonstrate how to use the Proxy design pattern in real-world code, let's talk about servers in a high-end restaurant (as we did for Facade and for Adapter).

A waiter at a hotel restaurant shows the daily menu

For this demo, let's imagine that servers at a restaurant primarily do three things:

  1. Take the patron's order.
  2. Deliver the patron's order.
  3. Process the diner's payment.

With these assumptions, we can create an interface for these actions (this interface being the Subject participant):

/// <summary>
/// The Subject interface which both the RealSubject and proxy will need to implement
/// </summary>
public interface IServer  
{
    void TakeOrder(string order);
    string DeliverOrder();
    void ProcessPayment(string payment);
}

Now let's create a real Server class (the RealSubject participant):

/// <summary>
/// The RealSubject class which the Proxy can stand in for
/// </summary>
class Server : IServer  
{
    private string Order;
    public void TakeOrder(string order)
    {
        Console.WriteLine("Server takes order for " + order + ".");
        Order = order;
    }

    public string DeliverOrder()
    {
        return Order;
    }

    public void ProcessPayment(string payment)
    {
        Console.WriteLine("Payment for order (" + payment + ") processed.");
    }
}

Now imagine for a second that our Server instance is an experienced server who is helping train a newly-employed server. That new employee, from the patron's perspective, is still a server and will still behave as such. However, the new trainee cannot process payments yet, as he must first learn the ropes of taking and delivering orders.

We can create a Proxy to model this new employee. The Proxy will need to maintain a reference back to the Server instance so that it can call the Server instance's ProcessPayment() method:

/// <summary>
/// The Proxy class, which can substitute for the Real Subject.
/// </summary>
class NewServerProxy : IServer  
{
    private string Order;
    private Server _server = new Server();

    public void TakeOrder(string order)
    {
        Console.WriteLine("New trainee server takes order for " + order + ".");
        Order = order;
    }

    public string DeliverOrder()
    {
        return Order;
    }

    public void ProcessPayment(string payment)
    {
        Console.WriteLine("New trainee cannot process payments yet!")
        _server.ProcessPayment(payment);
    }
}

As you can see, the NewServerProxy implements its own TakeOrder() and DeliverOrder() methods, and calls the Server class's ProcessPayment() method. Since they both implement IServer, the NewServerProxy can be used any place the Server can be used.

Will I Ever Use This Pattern?

Probably. If you've ever had a need to change the behavior of an existing object without actually changing the definition of that object, the Proxy pattern can allow you to do that. Further, I can see this being very useful in testing scenarios, where you might need to replicate a class's behavior without fully implementing it.

Summary

The Proxy pattern seeks to create a "stand-in" object which can be used in place of an existing object and maintains a reference to an instance of said existing object. To fulfill the pattern, the Proxy object must be able to be used anywhere the replaced object can be used.

As always, I like to provide code with my tutorials, so the repository for this pattern is over on GitHub and contains all of the sample code used here.

And, while you're here, check out our wine specials. There's sure to be something to suit your taste.

Happy Coding!

Get My eBook FREE!

Did you enjoy this post? This article and 21 others are also in my free eBook, "The Daily Design Pattern", which you can get just by signing up for my email list.