Proxy Design Pattern

Proxy is a very simple yet very powerful design pattern that is used a lot in software design. In fact, many people use Proxy Design Pattern but do not use the nomenclature. Please check out my video on the Proxy Design Pattern.

This post contains some additional information and source code of the applications shown in the video.

When we think of the Proxy Design Pattern, we think of a Proxy object that works like a “middleman”. This object sits in between the client object and the service object (called Real Subject in Proxy Design Pattern lingo), intercepts messages between the client and the service objects and provides additional functionality. The additional functionality could be one or more of the following:
1. Simply the communication between the the client and the service
2. Protect the service object from unauthorized access.
3. Do some additional data processing before the message is handed over to the service. The proxy object could do some data processing when the information is flowing back from the service to the client object.
4. Defer the instantiation of the service object as much as possible if the service object instantiation is costly.

And list of Proxy Object functionality is not confined to the bullets listed above. Any time we need a “middleman” to do any type of additional work, we could include a proxy object.

The class diagram of the Proxy Design Pattern is:

Proxy Design Pattern Class Diagram

 

The Proxy and the Real Subject are expected to provide a common interface to the client object. This is possible because their classes implement a common interface which is called AbstractSubject in the class diagram.

Wikipedia covers three usage scenarios of Proxy objects here.

The YouTube video covers the three usage scenarios described on the Wikipedia page. The scenarios are:
a. Remote Proxy – This proxy is useful when the client and the real subject reside in different address spaces. The service object in our example is a web service object hosted by United Postal Service (UPS). The methods on this remote service are invoked by the client object via a proxy that is generated by Visual Studio. To the client object, this service appears to be a local object and the service invocation appears just a local method invocation. But this proxy object (service reference) works with the .net runtime to convert these method invocations to web requests on the UPS Service object and so the service reference object works like a remote proxy. This video just shows how to create this service reference (remote proxy). If you are interested in using the UPS API for address validation and package tracking, it is discussed here and here.

b. Protection Proxy – This proxy prevents unauthorized access to an object. In our example, a protection proxy checks the security principal of the logged in user in a windows desktop application and allows or prohibits access to the real subject if the logged in user is in the administrators security group. This is the source code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
 
namespace ProxyDemoConsoleApplication
{
    class Proxy
    {
        public void DoSomething()
        {
            //code snippet in protection proxy method
            //get security principal associated with the
            //logged in user
 
            WindowsIdentity identity = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(identity);
 
            //check user access
            //is the user admin
            if (principal.IsInRole("Administrators"))
                RealSubject = new RealSubject();
                //invoke real subject method
                RealSubject.DoSomething();
            else  //if not, throw an exception
            {
                throw new SecurityException("Cannot access this object");
            }
 
        }
    }
}

c. Virtual Proxy – This proxy defers the instantiation of a real subject because the instantiation process is costly. The example in the video is a Customer Account class which holds a collection of Transactions. When you create Customer Account Class Instance, all the transactions on the customer account ever since it was opened is loaded an attribute on the object. The ShowBalance method on the class sums up the amounts associated with all transactions. This is the Customer Account class.

public class CustomerAccount: ICustomerAccount
    {
 
        IList AllTransactions = new List();
        String _customerId = null;
 
            public CustomerAccount(String customerId) {
 
            _customerId = customerId;
 
            //costly operation - load all transactions since the account was opened
            //.........
            //.........
 
        }
 
        public Decimal ShowBalance()
        {
            Decimal Balance = 0;
 
            //loop through each transaction and add the amount to determine total balance
            foreach(Transaction tr in AllTransactions)
            {
                Balance += tr.Amount;
            }
 
            return Balance;
        }
 
    }

The details of the Transaction object are not very relevant but the code is provided for the sake of completion.

    //abstract subject
    public interface ICustomerAccount
    {
        Decimal ShowBalance();
    }

Both Real Subject (CustomerAccount) and Proxy (ProxyCustomerAccount) implement a common interface.

public  class Transaction
    {
        DateTime _transactionDate; //date the transaction was done
        Decimal _amount; //transaction amount
        public Transaction(DateTime transactionDate, Decimal amount)
        {
            _transactionDate = transactionDate;
            _amount = amount;
       }
        public Decimal Amount
        {
            get
            {
                return _amount;
            }
        }
    }

The Proxy object’s constructor does not instantiate the real subject immediately. It creates the real subject only when the ShowBalance method is invoked. This is the code:

    //virtual proxy
    public class CustomerAccountProxy : ICustomerAccount
    {
 
        CustomerAccount realSubject = null;
        String customerID;
 
        public CustomerAccountProxy(String custId)
        {
            //store the customer ID as a private attribute
            customerID = custId;
            //defer the creation of customer account until
            //ShowBalance is called
            //do nothing for the time being
        }
 
        public Decimal ShowBalance()
        {
            //now create the real subject because the balance
            //cannot be determined until the real subject is loaded
            realSubject = new CustomerAccount(customerID);
            return realSubject.ShowBalance();
 
        }
    }

So the Client Object, which is a console application’s main method, can call methods on the Real Subject via the Proxy Object like this.

class Program
    {
        public static void Main()
        {
            //client code
            CustomerAccountProxy Proxy = new CustomerAccountProxy("12345678");
            //do some work
            //...
            //...
            //...
            //the real subject gets created when the next line is executed
            Console.WriteLine(Proxy.ShowBalance());
            Console.ReadKey();
        }
    }

All code is c# and targets .Net Framework 4.5. I’d love to hear from you on your experience with the Proxy Design Pattern and also your feedback on this post and the YouTube Video.