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
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.
RealSubject
is the class which contains the logic to be executed.Proxy
object contains the instance ofRealSubject
and controls access to itssomeAction()
method.- Client cannot use a
RealSubject
instance directly. It must obtain an instance ofProxy
first. However, this delegation of responsibility fromRealSubject
toProxy
is transparent forClient
. I.e.client
still thinks that its working withRealSubject
. - To enable this substitution of
RealSubject
byProxy
one more layer of abstraction exists aboveProxy
&RealSubject
, i.e. theSubject
Class. Client
contains a reference to thisSubject
class.- 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()
onSubject
which actually contains an object ofProxy
, thenProxy
invokessomeAction()
method onRealSubject
. So,Proxy
gets 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 whichProxy
gets to do on the incoming request is one of the primary advantages of using theProxy
Pattern. Proxy
can do the same processing in reverse also when it receives a response fromRealSubject
object. After processing/massaging the responseProxy
returns the final response toClient
.- In the whole process Client thinks its using the
RealSubject
directly, however, in reality its theProxy
object 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
TextFile
is an abstract class which is the base class for all text files.TextFile
has 2 abstract methods -getNameWithPath()
which returns name of the file with system path to of the file appended, andgetFileContents()
which returns the contents of the file as a FileInputStream instance.TextFile
also has a static method for returning an instance to it calledgetTextFileInstance()
. This is where Proxy part kicks in as this method instead of returning aRealTextFile
instance returns aTextFileProxy
instance.RealTextFile
is a sub-class ofTextFile
and it contains the actual contents of a file.TextFileProxy
is also a sub-class ofTextFile
. As mentioned earlier, when a new TextFile instance is requested via thegetTextFileInstance()
then aTextFileProxy
instance 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 usinggetFileContents()
method. At this point, TextFileProxy creates a new instance of RealTextFile with thefileNameWithPath
value stored in it.TextFileProxy then assigns the RealTextFile instance to the class attributerealTextFile
and then returns the contents of the text file usingrealTextFile.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
TextFileProxy
instance whentextFile.getNameWithPath()
is invoked. - Then, the
FileInputStream
's reference object's information is printed when thetextFile.getFileContents()
is invoked textFile.getFileContents()
actually invokesTextFileProxy
’sgetFileContents()
which in turn instantiates and invokesRealTextFile
instance'sgetFileContents()
- 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