This chapter covers the proxy pattern.
GoF Definition
Provide a surrogate or placeholder for another object to control access to it.
Concept
A proxy is basically a substitute for an intended object. Access to the original object is not always possible due to many factors. For example, it is expensive to create, it is in need of being secured, it resides in a remote location, and so forth. The proxy design pattern helps us in similar contexts. When a client deals with a proxy object, it assumes that it is talking to the actual object. So, in this pattern, you may want to use a class that can perform as an interface to something else.
Real-World Example
In a classroom, when a student is absent, his best friend may try to mimic his voice during roll call to try to get attendance for his friend.
Computer-World Example
In the programming world, to create multiple instances of a complex object (heavy object) is costly . So, whenever you are in need, you can create multiple proxy objects that point to the original object. This mechanism can also help save your system/application memory. An ATM can implement this pattern to hold proxy objects for bank information that may exist on a remote server.
Note
In the java.lang.reflect package, you can have a Proxy class and an InvocationHandler interface that supports a similar concept. The java.rmi.* package also provides methods through which an object on one Java virtual machine can invoke methods on an object that resides in a different Java virtual machine.
Illustration
In the following program, I am calling the doSomework() method of the proxy object, which in turn, calls the doSomework() method of an object of ConcreteSubject. When clients see the output, they do not know that the proxy object does the trick.
Class Diagram
Package Explorer View
Implementation
Output
Q&A Session
- 1.
What are the different types of proxies?
These are the common types:Remote proxies . Hide the actual object that stays in a different address space.
Virtual proxies . Perform optimization techniques, such as the creation of a heavy object on a demand basis.
Protection proxies . Deal with different access rights.
Smart reference . Performs additional housekeeping work when an object is accessed by a client. A typical operation is counting the number of references to the actual object at a particular moment.
- 2.You could create the ConcreteSubject instance in the proxy class constructor, as follows.class Proxy extends Subject{static Subject cs;public Proxy(){//Instantiating inside the constructorcs = new ConcreteSubject();}@Overridepublic void doSomeWork(){System.out.println("Proxy call happening now...");cs.doSomeWork();}}
Is this correct?
Yes, you could do that. But if you follow this design, whenever you instantiate a proxy object, you need to instantiate an object of the ConcreteSubject class also. So, this process may end up creating unnecessary objects. You can simply test this with the following piece of code and the corresponding outputs.
Alternate Implementation
Output Without Lazy Instantiation
Analysis
Notice that you have created two proxy instances.
Now, try our earlier approach with lazy instantiation. (Remove the proxy constructor and uncomment the lazy instantiation stuffs).
Output with Lazy Instantiation
Analysis
- 3.
But in this lazy instantiation technique , you may create unnecessary objects in a multithreaded application. Is this correct?
Yes. In this book, I am presenting simple illustrations only, so I have ignored that part. In the discussions on the singleton pattern, I analyzed some alternative approaches to deal with a multithreaded environment. You can always refer to those discussions in situations like this. (For example, in this particular scenario, you can implement a synchronization technique, or a locking mechanism, or a smart proxy, and so forth to ensure that a particular object is locked before you grant access to the object.)
- 4.
Can you give an example of a remote proxy?
Suppose, you want to call a method of an object but the object is running in a different address space (e.g., different locations or different computers, etc.). How do you proceed? With the help of remote proxies, you can call the method on the proxy object, which in turn forwards the call to the actual object that is running on the remote machine. This type of need can be realized through well-known mechanisms like ASP.NET, CORBA, C#’s WCF (version 3.0 onward), or Java’s RMI (Remote Method Invocation).
Figure 6-3 demonstrates a simple remote proxy structure. - 5.
When can you use a virtual proxy?
It can be used to avoid multiple loadings of an extremely large image.
- 6.
When can you use a protection proxy?
The security team in an organization can implement a protection proxy to block Internet access to specific websites.
Consider the following example, which is basically a modified version of the proxy pattern implementation described earlier. For simplicity, let’s assume that at present, we have only three registered users who can exercise the doSomeWork() proxy method. Apart from them, if any other user (say, Robin) tries to invoke the method, the system will reject those attempts. You must agree, when the system will reject this kind of unwanted access; there is no point in making a proxy object. So, if you avoid instantiating an object of ConcreteSubject in the Proxy class constructor, you can easily avoid these kinds of additional objects creation.
Now go through the modified implementation.
Modified Package Explorer View
Modified Implementation
Modified Output
- 7.
Proxies act like decorators. Is this correct?
You can implement a protection proxy similar to decorators but you should not forget the intent. Decorators focus on adding responsibilities, but proxies focus on controlling the access to an object. Proxies differ from each other with their types and implementations. Also, in general, proxies work on the same interface but decorators can work on extended interfaces. So, if you can remember their purposes, in most cases, you can clearly distinguish them from decorators.
- 8.
What are the cons associated with proxies?
If you are careful enough in your implementation, the pros are much greater than the cons, butYou can raise your concern about the response time. Since you are not directly talking to the actual object, it is possible that the response time through these proxies is longer.
You need to maintain additional code for the proxies.
A proxy can hide the actual responses from objects, which may create confusion in special scenarios.