This tutorial explain the basic concept of proxy factory design pattern and how to use them. This is one of the pattern I have published as part of our Design pattern in Java series. If you are interested in receiving updates, please subscribe our newsletter.
Application is often a collection of components and in most of the situations it may be the case that a component should be loaded until it is first accessed by the Client. Reasons may be that the component in consideration may be using most of the system resources.
For example, consider the Microsoft Word Application which is providing Printer Service and the Help System. It should not be the case that both the Printer Service and the Help System should be loaded during the Application start up.
Imagine what would be the case if the Client after starting the Word Application is accessing other part of the System and not the Printer and the Help Service. Definitely it will lead to a slow-response time because the Components are un-necessarily loaded.
Proxy Design Pattern
Proxy Design Pattern comes into picture here as it defers the Object Creation process of memory-intensive components thereby speeding up the Application. Now, let us see how to design the Proxy design pattern.
also read:
Imagine that we are creating an Application that is making use of Email Service as well as other set of services. Assuming that the Client Application won’t be always accessing the Email Service, the Email Service is an ideal candidate to be modeled as a Proxy. Let us look into the class definitions,
EMailService.java
package tips.pattern.proxy.virtual; public interface EMailService { public void sendMail(String receiver, String subject, String text); public void receiveMail(String receiver); }
The above is the interface declaration for EMailService
which provides methods for sending and receiving mails through its sendMail()
and receiveMail()
methods. Now, let us look into the real implementation for this EMailService
interface.
RealEMailService.java
package tips.pattern.proxy.virtual; public class RealEMailService implements EMailService{ @Override public void sendMail(String receiver, String subject, String text) { System.out.println("Sending mail to '" + receiver + "'" + " with subject '" + subject + "'" + " and message '" + text + "'"); } @Override public void receiveMail(String receiver) { System.out.println("Receiving mail from '" + receiver + "'"); } }
As we see, the above class should be loaded on demand only, i.e, an instance for the above class should be created only when the client is accessing for the first time. Now, let us create a proxy class for the above real implementation.
It should be noted that the proxy class should conform to the methods of the real implementation class so that the clients are provided with a single unified interface. In many instances, the clients are even unaware of the fact that they are making calls on the proxy.
The following proxy implementation implements the EMailService
interface and just delegates the method calls to the real implementation. It means that the proxy class should maintain a reference to the original real class object and should create the real object on demand.
ProxyEMailService.java
package tips.pattern.proxy.virtual; public class ProxyEMailService implements EMailService{ private RealEMailService emailService; @Override public void receiveMail(String receiver) { if (emailService == null){ emailService = new RealEMailService(); } emailService.receiveMail(receiver); } @Override public void sendMail(String receiver, String subject, String text) { if (emailService == null){ emailService = new RealEMailService(); } emailService.sendMail(receiver, subject, text); } }
Now, let us look into the Application class which is going to be accessible by the Clients.
Application.java
package tips.pattern.proxy.virtual; public class Application { public EMailService locateEMailService(){ EMailService emailService = new ProxyEMailService(); return emailService; } }
In the above class, we actually create an object reference for the proxy implementation and not for the real implementation. Clients are unaware that they are dealing with the proxy object. Given below is a simple Application client that is making use of the EMailService
class,
ApplicationClient.java
package tips.pattern.proxy.virtual; public class ApplicationClient { public static void main(String[] args) { Application application = new Application(); EMailService emailService = application.locateEMailService(); emailService.sendMail("abc@gmail.com", "Hello", "A test mail"); emailService.receiveMail("abc@gmail.com"); } }
The output of this is,
Sending mail to 'abc@gmail.com' with subject 'Hello' and message 'A test mail' Receiving mail from 'abc@gmail.com'