Friday, February 28, 2014

Structural Design Patterns: Proxy Design Pattern



The GoF book says you can use the Proxy design pattern to, “Provide a surrogate or placeholder for another object to control access to it”.
The Proxy design pattern is your best friend when you have a remote object you want to work with and make that object seem local, or when you want to control access to that remote object in some way. 
Proxy means ‘in place of’. In attendance roll call, we give proxy for our friends in college right? ‘Representing’ or ‘in place of’ or ‘on behalf of’ are literal meanings of proxy and that directly explains proxy design pattern.


You need to support resource-hungry objects, and you do not want to instantiate such objects unless and until they are actually requested by the client.

There are various connection techniques you can use in Java, such as RMI, to enable proxies to talk to remote objects. Since all you have to do is send text back and forth from automate proxy to automate server.
Sometimes we need the ability to control the access to an object. For example if we need to use only a few methods of some costly objects we'll initialize those objects when we need them entirely. Until that point we can use some light objects exposing the same interface as the heavy objects. These light objects are called proxies and they will instantiate those heavy objects when they are really need and by then we'll use some light objects instead.

Intent
  • Provide a surrogate or placeholder for another object to control access to it.
  • Use an extra level of indirection to support distributed, controlled, or intelligent access.
  • Add a wrapper and delegation to protect the real component from undue complexity.

There are four common situations in which the Proxy pattern is applicable.

1)      A virtual proxy is a placeholder for "expensive to create" objects. The real object is only created when a client first requests/accesses the object.
e.g. In place of a complex or heavy object use a skeleton representation. When an underlying image is huge in size, just represent it using a virtual proxy object and on demand load the real object.
2)      A remote proxy provides a local representative for an object that resides in a different address space. This is what the "stub" code in RPC and CORBA provides.
E.g Think of an ATM implementation, it will hold proxy objects for bank information that exists in the remote server , Remote Server Object RMI
3)      protective proxy controls access to a sensitive master object. The "surrogate" object checks that the caller has the access permissions required prior to forwarding the request.
4)      Smart ReferenceJust we keep a link/reference to the real object a kind of pointer.
A smart proxy interposes additional actions when an object is accessed. Typical uses include:
i)             Counting the number of references to the real object so that it can be freed automatically when there are no more references (aka smart pointer),
ii)            Loading a persistent object into memory when it's first referenced,
iii)           Checking that the real object is locked before it is accessed to ensure that no other object can change it.
 
Common situation: Java Proxy objects
  • Virtual Proxies: delaying the creation and initialization of expensive objects until needed, where the objects are created on demand (For example creating the RealSubject object only when the doSomething method is invoked).
  • Remote Proxies: providing a local representation for an object that is in a different address space. A common example is Java RMI stub objects. The stub object acts as a proxy where invoking methods on the stub would cause the stub to communicate and invoke methods on a remote object (called skeleton) found on a different machine.
  • Protection Proxies: where a proxy controls access to RealSubject methods, by giving access to some objects while denying access to others.
  • Smart References: providing a sophisticated access to certain objects such as tracking the number of references to an object and denying access if a certain number is reached, as well as loading an object from database into memory on demand.
    1:  public interface Animal {  
    2:       public void getSound();  
    3:  }
  Then implement same class with some implementation
1:  public class Lion implements Animal {  
2:       @Override  
3:       public void getSound() {  
4:            System.out.println("Roar");  
5:       }  
6:  }  


Below implemented InvocationHandler
1:  import java.lang.reflect.InvocationHandler;  
2:  import java.lang.reflect.Method;  
3:  public class AnimalInvocationHandler implements InvocationHandler {  
4:        private Object realSubject = null;  
5:       public AnimalInvocationHandler(Object realSubject) {  
6:        this.realSubject = realSubject;  
7:       }  
8:       @Override  
9:       public Object invoke(Object proxy, Method method, Object[] args)  
10:                 throws Throwable {  
11:            Object result = null;  
12:         try {  
13:          result = method.invoke(realSubject, args);  
14:         } catch (Exception ex) {  
15:          ex.printStackTrace();  
16:         }  
17:         return result;  
18:       }  
19:  }  

Test Class
1:  import java.lang.reflect.Proxy;  
2:  public class ProxyExample {  
3:       public static void main(String[] args) {  
4:            Animal realSubject = new Lion();  
5:            Animal proxy = (Animal) Proxy.newProxyInstance(realSubject.getClass()  
6:                .getClassLoader(), realSubject.getClass().getInterfaces(),  
7:                new AnimalInvocationHandler(realSubject));  
8:    proxy.getSound();  
9:       }  
10:  }  

Output :  Roar


Example 2 :  We're going to create a Image interface and concrete classes implementing the Image interface. ProxyImage is a a proxy class to reduce memory footprint of RealImage object loading.ProxyPatternDemo, our demo class will use ProxyImage to get a Image object to load and display as it needs.

1:  public interface Image {  
2:       void display();  
3:  }  

Create concrete classes implementing the same interface.
1:  public class RealImage implements Image {  
2:       private String fileName;  
3:       public RealImage(String fileName){  
4:          this.fileName = fileName;  
5:          loadFromDisk(fileName);  
6:         }  
7:       @Override  
8:         public void display() {  
9:          System.out.println("Displaying " + fileName);  
10:         }  
11:         private void loadFromDisk(String fileName){  
12:          System.out.println("Loading " + fileName);  
13:         }  
14:  }  

Implement Proxy class with same interface . 
1:  public class ProxyImage implements Image {  
2:       private RealImage realImage;  
3:       private String fileName;  
4:       public ProxyImage(String fileName){  
5:          this.fileName = fileName;  
6:         }  
7:        @Override  
8:         public void display() {  
9:          if(realImage == null){  
10:            realImage = new RealImage(fileName);  
11:          }  
12:          realImage.display();  
13:         }  
14:  }  
Use the ProxyImage to get object of RealImage class when required.

1:  public class ProxyPatternDemo {  
2:       public static void main(String[] args) {  
3:          Image image = new ProxyImage("test_10mb.jpg");  
4:          //image will be loaded from disk  
5:          image.display();   
6:          System.out.println("");  
7:          //image will not be loaded from disk  
8:          image.display();        
9:         }  
10:  }  


Notes :
1)       Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface.
2)       Adapter Design Pattern - The adapter implements a different interface to the object it adapts where a proxy implements the same interface as its subject.
3)       Decorator Design Pattern - A decorator implementation can be the same as the proxy however a decorator adds responsibilities to an object while a proxy controls access to it.
     4)   Decorator and Proxy have different purposes but similar structures. Both describe
         how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests
  • A proxy may hide information about the real object to the client.
  • A proxy may perform optimization like on demand loading.
  • A proxy may do additional house-keeping job like audit tasks.
  • Proxy design pattern is also known as surrogate design pattern.

No comments: