Wednesday, September 18, 2013

Proxy Pattern

In this blog, I'm going to write about Proxy pattern and it's applications.


Definition:

Proxy is a Structural design pattern which works 'on behalf of' or 'in place of' another object in order to access the later.

Here proxy objects are used to perform the work on somebody's behalf. We will use proxy objects in the following scenarios:
  1. Lot of boilerplate code is required in order to invoke the real object.
  2. The access to the real object is limited and all the access needs to go through the proxy.
  3. The real object is a remote object

Illustration:

Let us take an example.

Lets say there is a King who lives in a palace and he has all kind of antique jewelry, paintings etc. John has a hobby of collecting antique items and he wants to purchase some antique items from the king. 

But the king will not part with his antique pieces so easily. He misses his good old glorious days in this modern era and hence the person who wants to purchase has to sing and praise the qualities of the king. Uh, surely the king misses yesteryears..

However, John is not interested nor good enough in singing and praising the king and he is quite sure that he will not be able to persuade the King to sell his antiques. So John hatches a plan. He hires a person (say, Danny the dwarf) who is well versed with the nuances of the king and can get the job done. Cool, John has one less thing to worry about.

So, John will instruct Danny on what antique items he is interested in and pays Danny. Danny in turn will go to the palace, sing and flatter the King and persuade him to sell them. Danny then hands over the antiques to John.

Perfect!..We just described the Proxy pattern. Danny is the proxy here, who works on behalf of John. The king is the 'subject' and John the client.

Implementation:

In real world, we will have one interface and two implementation classes; one implemented by the proxy and one the real implementor.

Let's say the interface is AntiqueSale as below, with a method say sellPaintings(long _cost);
public interface AntiqueSale{

    public Painting sellPaintings(long _cost);

}

The real implementation of this interface will lie with the King. It will remove the painting from the king's inventory and return it to the purchaser.
public class AntiqueSaleRealImpl{

    public Painting sellPaintings(long _cost){
              /*remove from inventory*/
              /*Other housekeeping stuff*/
              
              return painting;
    }
}

Lets take a look at the proxy implementation. It will have a reference to the real implementation and then sing, convince the king and finally would invoke the real implementation to get the antiques.

public class AntiqueSaleProxyImpl{
    private AntiqueSale antique = new AntiqueSaleRealImpl();

    public Painting sellPaintings(long _cost){
              /*Sing and praise the King*/
              /*Convince the King*/
              
              /*Invoke real implementation*/
              antique.sellPaintings(_cost);
              
              return painting;            
                            
    }

}

In real world, the proxy might do the following things:
  1. Implement the low level boiler plate code for remote access/security as in EJB remote proxies. 
  2. The real implementation might be fine grained which might require a series of invocations, and the proxy might act like a facade.

Dynamic proxies:

In the above example, we had to create a new proxy implementation class for every scenario which requires a proxy generation. So these proxies have to be generated at compile time.  But there could be scenarios where you would want to generate proxies on the fly at run time. Dynamic proxies come to our rescue to handle these situations.

java.lang.reflect package has an interface 'InvocationHandler'. This has a method invoke() which needs to be implemented. This method receives the method to be invoked as an argument, and the implementer of this interface can perform the necessary plumbing code before the actual method invocation.
public class GenericInvocationHandler implements InvocationHandler {
       Object invokeImpl;
       
       public GenericInvocationHandler(Object _invokeImpl){
               this.invokeImpl = _invokeImpl;
       }
       
       @Override
       public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {

                /*Do something before invoke*/
         method.invoke(invokeImpl, args);
                /*Do something after invoke*/
         return null;
 }
}

To create the proxy object, Proxy.newProxyInstance() could be invoked by passing in the required arguments as below. Note that a proxy class is generated at run time and returned back. Calls to hashcode(), toString(), equals() methods on the proxy class will be delegated to the actual implementor classes.

AntiqueSale antiqueProxy = (AntiqueSale) Proxy.newProxyInstance(AntiqueSale.class.getClassLoader(), new Class[]{AntiqueSale.class}, new GenericInvocationHandler(obj));


Applications of dynamic proxy:

  1. In Spring framework to implement AOP. Using dynamic proxies, Spring framework will be able to apply the 'advices'.
  2. Hibernate framework also extensively uses proxies.
  3. EJB remote proxy

No comments:

Post a Comment