Proxy pattern

Proxy pattern is one of the structural design patterns
As the name indicates, this pattern is used to define a proxy for a real object.

We know that proxy means, something in place of other thing or just a representation of something else.

Let’s understand Proxy Pattern in this way


We have some heavy object which contains lot of methods in it but always it is not required to use all the methods of the complex heavy object.
So, in this case, we will use some light objects which exposes the same interface as heavy object.

Using that, we can use only required methods of heavy object

So,This light object is called as “Proxy”

Proxy object acts like a real object but its not the actual real object.

Client basically access Proxy object and Proxy object in turn access real object,In this way it also helps to control the access of real object.

Proxy_pattern_1


Controlling the access of the real objects has many benefits


1) Controlling when a costly object needs to be instantiated

2) Giving different access rights based on some roles to an object

3) Providing a sophisticated way of accessing and referencing remote objects(objects in other system)

Now let’s try to understand technically and implement it


In this pattern, client basically access Proxy object
Proxy object access actual object
So, we will have a common interface for both actual object and Proxy object

We can see the same in below diagram

Proxy_pattern_2

Subject – Interface implemented by the RealObject and representing its services. The interface must be implemented by the ProxyObject as well so that the proxy can be used in any location where the RealObject can be used.

ProxyObject
Proxy class to access the RealObject.

Implements the same interface implemented by the RealObject so that the Proxy can be substituted for the RealObject.

Controls access to the RealObject and also responsible for its creation and deletion.

There could be other responsibilities depend on the kind of proxy we are using.

RealObjectThe real object that the proxy represents.

Let’s implement Proxy pattern for below requirement

Requirement :

In email application, we use attachments sometime while sending an email.
User who reads an email might open an attachment or might not
So, send an attachment link only in the email rather than sending whole attachment content.
So that when user opens an attachment, we can load the attachment content.

Also control the access of real object to show attachment only for valid users
In this case, we use proxy pattern and send proxy object as an attachment which should call real object only when user opens an attachment.

Proxy_pattern_3

Let’s achieve it by coding

Step 1

Create an interface called “Email”

  1. package com.kb.proxy;
  2.  
  3. public interface Email {
  4.     public void showEmail(String user);
  5.  
  6. }
package com.kb.proxy;

public interface Email {
	public void showEmail(String user);

}

Step 2

Create a proxy class which implements this interface

  1. package com.kb.proxy;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. public class EmailProxy implements Email {
  7.  
  8.     private static List<String> userList;
  9.  
  10.     static {
  11.         userList = new ArrayList<String>();
  12.         userList.add("111");
  13.         userList.add("222");
  14.         userList.add("333");
  15.     }
  16.  
  17.     @Override
  18.     public void showEmail(String user) {
  19.         if (userList.contains(user)) {
  20.             Email email = new EmailWithAttachment();
  21.             email.showEmail(user);
  22.         } else {
  23.             throw new RuntimeException("Sorry, Access Denied");
  24.         }
  25.  
  26.     }
  27.  
  28. }
package com.kb.proxy;

import java.util.ArrayList;
import java.util.List;

public class EmailProxy implements Email {

	private static List<String> userList;

	static {
		userList = new ArrayList<String>();
		userList.add("111");
		userList.add("222");
		userList.add("333");
	}

	@Override
	public void showEmail(String user) {
		if (userList.contains(user)) {
			Email email = new EmailWithAttachment();
			email.showEmail(user);
		} else {
			throw new RuntimeException("Sorry, Access Denied");
		}

	}

}

Step 3

Create a real implementor class which implements this interface

  1. package com.kb.proxy;
  2.  
  3. public class EmailWithAttachment implements Email{
  4.  
  5.     @Override
  6.     public void showEmail(String user) {
  7.         System.out.println("Heavy operation to load attachment is done");
  8.        
  9.     }
  10.  
  11. }
package com.kb.proxy;

public class EmailWithAttachment implements Email{

	@Override
	public void showEmail(String user) {
		System.out.println("Heavy operation to load attachment is done");
		
	}

}

Step 4

Create client class which uses the proxy

  1. package com.kb.proxy;
  2.  
  3. public class EmailViewer {
  4.  
  5.     public static void main(String[] args) {
  6.         Email email  = new EmailProxy(); //Loading only proxy object
  7.        
  8.         //calling with valid user, This will actually loads real object
  9.         email.showEmail("111");
  10.        
  11.         //calling with invalid user, This will also loads real object
  12.         email.showEmail("444");
  13.  
  14.     }
  15.  
  16. }
package com.kb.proxy;

public class EmailViewer {

	public static void main(String[] args) {
		Email email  = new EmailProxy(); //Loading only proxy object
		
		//calling with valid user, This will actually loads real object
		email.showEmail("111");
		
		//calling with invalid user, This will also loads real object
		email.showEmail("444");

	}

}

Step 5

Run the client program and check the output

  1. Heavy operation to load attachment is done
  2. java.lang.RuntimeException: Sorry, Access Denied
  3.     at com.kb.proxy.EmailProxy.showEmail(EmailProxy.java:23)
  4.     at com.kb.proxy.EmailViewer.main(EmailViewer.java:12)
Heavy operation to load attachment is done
java.lang.RuntimeException: Sorry, Access Denied
	at com.kb.proxy.EmailProxy.showEmail(EmailProxy.java:23)
	at com.kb.proxy.EmailViewer.main(EmailViewer.java:12)

We can see that,
For valid user, proxy is making a call to real object and get the ouput
For Invalid user, proxy is not making a call to real object and throwing exception.

Proxy pattern is very similar to decorator pattern in the structure but decorator adds responsibilities to an object while a proxy controls access to it

When should we use Proxy pattern?


Whenever we need to provide a surrogate or placeholder for another object to control access to it
Whenever we need to add a wrapper to protect the real object
Whenever we need to load few details of the complex object and loading remaining details as and when required

Note :
This pattern is already implemented in Java Remote Method invocation(RMI) and Hibernate lazy loading

About the Author

Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on