Proxy Design Pattern in Java
This tutorial explains Proxy design pattern in java with class diagrams and example code.
Introduction
Proxy Design Pattern is a structural design pattern among the Gang Of Four(GOF)Article on GOF Patterns & their types Design Patterns. A structural design pattern deals with how the relationships between objects are realized to make the design better.
What is Proxy Design Pattern
Proxy pattern specifies a design where substitute or placeholder object is put in-place of the actual target object to control access to it. Client accesses the proxy object to work with the target object. There are many practical usages and applications of using a target object through a proxy. Lets have a look at the major ones.
Usages and Applications of Proxy Pattern
  
  
  
  
Class Diagram for Proxy Design Pattern
   Explanation of Class Diagram
Explanation of Class Diagram
   OUTPUT of the above code
  
        
Explanation of Code & Class Diagram
The Java class diagram above depicts proxy pattern implemented for a text file reader application where -
  
      
  
  
  
  
 OUTPUT of the above code
  
        
Explanation of Code & Class Diagram
The Java class diagram above depicts proxy pattern implemented for a text file reader application where - 
- Remote Proxy - Using a remote proxy, clients can access objects on a remote location as if they are co-located with them. In Java, using the java.rmi.Remote interface of RMI is an example of this.
- Virtual Proxy - A virtual proxy creates an instance of an expensive Object only on demand. I.e. it saves on resources by not creating an instance of an Object heavy on resources until it is needed.
- Protection Proxy - A protection proxy regulates access to the original object. Its similar to authroization i.e. object access is controlled based on access rights defined for that Object.
- Smart Reference - A smart reference proxy does additional actions when an object is accessed which typically include things like loading a persistent object into memory when its first referenced, locking of objects to avoid inconsistencies in data held by the object etc. It can also keep track of current usage of the real object and in case it is no longer used then a smart reference unloads the object from memory to load it back only when its needed.
 
- RealSubjectis the class which contains the logic to be executed.
- Proxyobject contains the instance of- RealSubjectand controls access to its- someAction()method.
- Client cannot use a RealSubjectinstance directly. It must obtain an instance ofProxyfirst. However, this delegation of responsibility fromRealSubjecttoProxyis transparent forClient. I.e.clientstill thinks that its working withRealSubject.
- To enable this substitution of RealSubjectbyProxyone more layer of abstraction exists aboveProxy&RealSubject, i.e. theSubjectClass.
- Clientcontains a reference to this- Subjectclass.
- Subject reference in Client contains an instance of Proxy class (which is possible as both Proxy and RealSubject are children of Subject)
- When client invokes someAction()onSubjectwhich actually contains an object ofProxy, thenProxyinvokessomeAction()method onRealSubject. So,Proxygets the request fromClient, does some work on incoming request, such as authentication/loading of value/remote access initiatation etc and invokes thesomeAction()method onRealSubject. This extra work whichProxygets to do on the incoming request is one of the primary advantages of using theProxyPattern.
- Proxycan do the same processing in reverse also when it receives a response from- RealSubjectobject. After processing/massaging the response- Proxyreturns the final response to- Client.
- In the whole process Client thinks its using the RealSubjectdirectly, however, in reality its theProxyobject which controls access toRealSubject.
 
Code for the classes shown in Java Class Diagram
    //TextFile.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public abstract class TextFile{
  public abstract String getNameWithPath();
  public abstract FileInputStream getFileContents() throws java.io.FileNotFoundException;
  public static TextFile getTextFileInstance(String fileNameWithPath){
    return new TextFileProxy(fileNameWithPath);
  }
}
//RealTextFile.java
import java.io.FileInputStream;
import java.io.File;
import java.io.FileNotFoundException;
public class RealTextFile extends TextFile{
  private String fileNameWithPath;
  public RealTextFile(String fileNameWithPath){
    this.fileNameWithPath=fileNameWithPath; 
  } 
  public String getNameWithPath(){
    return this.fileNameWithPath;
  }
  public FileInputStream getFileContents() throws FileNotFoundException{
    File file=new File(this.fileNameWithPath);
    return new FileInputStream(file);
  }  
}
//TextFileProxy.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class TextFileProxy extends TextFile{
  private String fileNameWithPath;
  RealTextFile realTextFile=null;
  public TextFileProxy(String fileNameWithPath){
    this.fileNameWithPath=fileNameWithPath; 
  } 
  public String getNameWithPath(){
    return this.fileNameWithPath;
  }
  public FileInputStream getFileContents() throws FileNotFoundException{
    this.realTextFile=new RealTextFile(this.fileNameWithPath);
    return realTextFile.getFileContents();
  }  
} 
//Client.java
import java.io.FileNotFoundException;
public class Client{
  public static void main(String args[]){
    TextFile textFile=TextFile.getTextFileInstance("C:\\tests\\test1.txt");
    System.out.println("TextFile's name with path is->"+textFile.getNameWithPath());
    //Till here TextFileProxy instance is created with the realTextFile instance in it being null
   try{
      System.out.println("TextFile's content ->"+textFile.getFileContents());
    }catch(FileNotFoundException fnfe){
      System.out.println("FileNotFoundException exception thrown");
    } 
  //At this point an instance of RealTextFile has been created
  } 
}TextFile's name with path is->C:\tests\test1.txt TextFile's content ->java.io.FileInputStream@5de9d0e3
- TextFileis an abstract class which is the base class for all text files.
- TextFilehas 2 abstract methods -- getNameWithPath()which returns name of the file with system path to of the file appended, and- getFileContents()which returns the contents of the file as a FileInputStream instance.
- TextFilealso has a static method for returning an instance to it called- getTextFileInstance(). This is where Proxy part kicks in as this method instead of returning a- RealTextFileinstance returns a- TextFileProxyinstance.
- RealTextFileis a sub-class of- TextFileand it contains the actual contents of a file.
- TextFileProxyis also a sub-class of- TextFile. As mentioned earlier, when a new TextFile instance is requested via the- getTextFileInstance()then a- TextFileProxyinstance is returned which just holds the file name & path String value. The actual instance of a file, i.e. a RealTextFile instance, is only created by a TextFileProxy when the Client wants to get the contents of the text file using- getFileContents()method. At this point, TextFileProxy creates a new instance of RealTextFile with the- fileNameWithPathvalue stored in it.TextFileProxy then assigns the RealTextFile instance to the class attribute- realTextFileand then returns the contents of the text file using- realTextFile.getFileContents()
- If you take a look at the code in main()method in Client class then initially a new TextFile instance is created using the static methodgetTextFileInstance(). On printing the file name with path it gets printed from TextFileProxy instance.
- Next when the textFile.getFileContents()is invoked, then internally RealTextFile's instance is invoked as explained above and a FileInputStream object is returned.
- In the output - - First the file's path is printed from TextFileProxyinstance whentextFile.getNameWithPath()is invoked.
- Then, the FileInputStream's reference object's information is printed when thetextFile.getFileContents()is invoked
- textFile.getFileContents()actually invokes- TextFileProxy’s- getFileContents()which in turn instantiates and invokes- RealTextFileinstance's- getFileContents()
 
- First the file's path is printed from 
Gang of Four (GOF) Design Patterns on JavaBrahman
Creational Patterns: Factory method PatternFactory Method Design Pattern in Java Builder PatternBuilder Design Pattern in Java Prototype PatternPrototype Design Pattern in Java
Behavioral Patterns: Chain of Responsibility PatternChain of Responsibility Design Pattern in Java Observer PatternObserver Design Pattern in Java Iterator PatternIterator Design Pattern in Java State PatternState Design Pattern in Java Memento PatternMemento Design Pattern in Java Visitor PatternVisitor Design Pattern in Java Strategy PatternStrategy Design Pattern in Java Template Method PatternTemplate Method Design Pattern in Java
Structural Patterns: Adapter PatternAdapter design pattern in Java Composite PatternComposite Design Pattern in Java Facade PatternFacade Design Pattern in Java Proxy Pattern Java Proxy Design Pattern in Java
Analysis of Patterns: Strategy vs State PatternStrategy Design Pattern versus State Design Pattern
Creational Patterns: Factory method PatternFactory Method Design Pattern in Java Builder PatternBuilder Design Pattern in Java Prototype PatternPrototype Design Pattern in Java
Behavioral Patterns: Chain of Responsibility PatternChain of Responsibility Design Pattern in Java Observer PatternObserver Design Pattern in Java Iterator PatternIterator Design Pattern in Java State PatternState Design Pattern in Java Memento PatternMemento Design Pattern in Java Visitor PatternVisitor Design Pattern in Java Strategy PatternStrategy Design Pattern in Java Template Method PatternTemplate Method Design Pattern in Java
Structural Patterns: Adapter PatternAdapter design pattern in Java Composite PatternComposite Design Pattern in Java Facade PatternFacade Design Pattern in Java Proxy Pattern Java Proxy Design Pattern in Java
Analysis of Patterns: Strategy vs State PatternStrategy Design Pattern versus State Design Pattern
