Proxy Design Pattern

Since Mr. SuperX was not so reachable, he has hired a PA.
Besides making him easily reachable, the PA helps filter and format the messages.
Moreover, it also shortens the time of interaction from his busy schedule.

In short, the PA acts as a Proxy for Mr. SuperX.

Its a structural design pattern simplifying the communication with an object which we can’t make it available locally or directly.

Some of the reason behind such objects could be like they are remote objects, they are secured, vulnerable or expensive objects. In such cases, a local representative called proxy, proves very useful. It provides the impression of the real object making the client interaction easy. It also helps us collect the client’s objective and pass it to the real object with the necessary checks.

A proxy may look similar to an adapter. But, whereas an adapter wraps an object to provide a suitable interface, the proxies hide the communication to the real object. As regards the interfaces, the proxies, in fact, mostly share the same interface with the real object, to make it easy for the clients.

Example usage of Proxy Patterns

Lets look at some real time use cases to understand the scenarios where we can use the proxies.

  • Remote Proxy : Lets think of a database, a webservice or a network storage. Unlike the local objects, we need to follow complex networking protocols to interact with these objects. But, the remote proxies can make it easy for the clients in such cases.
    • A remote proxy is a local object that hides the complexities in communication with the remote objects from the clients.
    • Some examples of remote proxy are – Http client, Ftp client, Jdbc client etc.
  • Virtual Proxy : When the real objects are expensive, create a lighter version for the user to interact. Then collect the user interaction on the lighter version, so that we can pass the same to work on the original expensive version. Some examples can be:
    • A Video Editor using lighter proxy version to work on the high resolution videos.
    • A video or an image browser using low resolution copies.
  • Protection Proxy : When the real objects are secured or vulnerable to use, this proxy in between can provide the required security checks. For example :
    • The corporate proxies to access the internet, which can otherwise be misused.
    • A reverse proxy, providing a central control on the web traffics for multiple domains.

 

How does the pattern work?

In this section we will look at couple of examples with diagrams to show how can we use proxies for our use cases.

Example 1

The diagram shows an example of a virtual proxy to make an video editor memory efficient.

Loading very high resolution videos will consume lot of memory but, we need the visuals for our editing purpose. Hence, as we can see, the editor creates the proxies(lighter versions) of these high resolution videos for the editing purpose.

  • While editing, the user works on the lighter proxies, as if they are working on the original videos! Here we collect all the user editing requirements.
  • Finally, the editor passes the user choice on the proxies, so that the merge module can do the merging on the original videos. 
Example 2

As the diagram shows, the proxy provides an indirection where we can control the access to the real object.

In this case, the corporate proxy monitors, filters, caches or secures the access requests to actual web destinations.

In a similar way, the remote proxies hides the complexities of communication with the remote objects.

A Simple Proxy Demo

This is a simple demo, showing how a proxy works. The comments printed in the program describes the significance of each component inline.

package spectutz.dp.struct.proxy;

public class ProxyDemoClient {
	
	public static void main(String[] args) {
		System.out.println("When the client calls the proxy,"
				+"\n the proxy communicates the intent to the real object.");
		
		new RemoteEntityProxy().doSomething();
	}

}
//Output
/*
When the client calls the proxy,
 the proxy communicates the intent to the real object.

RemoteEntityProxy::doSomething
Establish the communication with the RemoteEntity to call doSomething() on it.
Since the RemoteEntity is a local one in this demo, we are calling it directly.

RemoteEntity - Doing something special !
*/
package spectutz.dp.struct.proxy;

public class RemoteEntityProxy implements IRemoteEntity {

	@Override
	public void doSomething() {
		System.out.println("\nRemoteEntityProxy::doSomething");
		System.out.println("Establish the communication with the RemoteEntity"
				+ " to call doSomething() on it.");
		System.out.println("Since the RemoteEntity is a local one in this demo,"
				+ " we are calling it directly.");
		new RemoteEntity().doSomething();
	}
}
package spectutz.dp.struct.proxy;

public class RemoteEntity implements IRemoteEntity{

	@Override
	public void doSomething() {
		System.out.println("\nRemoteEntity - Doing something special !");		
	}
}
package spectutz.dp.struct.proxy;

//Both the real object and it's proxy, usually share the same interface
public interface IRemoteEntity {	
	public void doSomething();	
}

Conclusion

In case an object is not available locally or not supposed to be accessed directly, the proxy provides a suitable local representation.

Even though its an indirection, it provides the clients the impression of working directly on the real object. Like a personal assistant, it acts as the face of the real object. And, manages the communication between clients and the real object.