Proxy objects or the surrogates provide a placeholder for another object to control access to that object. A proxy acts as a lightweight or the simplified version of the original object. It supports the same operations as the original object but may delegate those requests to the original object to achieve them.
The Proxy design pattern is a structural pattern in which a proxy class wraps the real subject class. The client code only interacts with the proxy class and not the real subject.
In this tutorial, we’ll learn how to implement a proxy design pattern.
Why Use Proxies?
There are three most common scenarios where we might need a proxy class:
- Virtual Proxy: When the subject is pretty resource-intensive to instantiate, we might choose to use this pattern. The proxy class we create here is known as a virtual proxy. Some example use cases would include loading very high-resolution images on a web page. The idea is to delay the creation of an expensive resource until the time it is needed
- Protection Proxy: We can also use a proxy class to control access to our real subject class. For instance, allowing users to access a website based on their specific user roles
- Remote Proxy: A real-world example of this implementation would be that of a Google Docs. The web browser holds the proxy objects locally which are then synced with the objects at the remote server
A Proxy design pattern has the following components:
- Subject: an interface defining the contract for the real subject
- RealSubject: this is the class we’ll want to have a proxy for
- Proxy: this is the proxy class for the real subject. Both Proxy and RealSubject classes implement the Subject interface
- Client: the class that interacts with the proxy via the Subject interface
Both the Proxy and RealSubject classes implement the Subject interface. Also, the client interacts with the Subject interface and so it hides the fact that the client is interacting with a proxy in place of the real subject.
The proxy class wraps the real subject and may delegate some requests to the real subject. However, not all requests are delegated to the subject class. A proxy is capable of handling some of the lighter responsibilities.
Most of the organizations provide restricted access to the internet within their premises. So, how is it implemented?
The idea is to create a protection proxy.
Let’s start by defining a WebServer interface:
Here, the makeRequest() method is responsible for making a call to the webserver with a specific endpoint.
Let’s now implement the RealWebServer class which does the actual job of hitting a URL via network API calls:
Finally, we’ll create a proxy server and expose it to our clients:
With this, all the blocked websites will remain unavailable within the premises:
In this tutorial, we explored the proxy design pattern.
A proxy pattern allows us to defer creating an expensive resource until it’s needed, control access to the real subject, or to represent a remote object locally.
The Java Reflection API relies on proxies. Also, the Hibernate lazy fetching logic internally makes use of this pattern.