The Proxy Design Pattern

The Proxy Design Pattern

Image courtesy: www.unsplash.com

Proxy means ‘in place of’, or ‘on behalf of’. These literal meanings of proxy directly explains Proxy Design Pattern.

Proxies are also called surrogates, placeholders, handles, and wrappers.

In a nutshell, a proxy “Controls and manage access to the object they are protecting”


When to use this pattern?

Proxy pattern is used when we need to create a wrapper to cover the main object’s complexity from the client.

Types of proxies

  1. Remote Proxy
  2. Virtual Proxy
  3. Protection Proxy
  4. Smart Proxy

Remote proxy:

“A remote proxy provides a local representative for an object in a different address space”.

They are responsible for representing the object located remotely. Talking to the real object might involve manipulation of data. All that logic is encapsulated in these proxies and the client application need not worry about them.

Virtual proxy:

“A virtual proxy basically creates expensive objects on demand”.

It is a placeholder for “expensive to create” objects. The real object is only created when a client first requests/accesses the object.

Protection proxy:

“A protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights”.

If an application does not have access to some resource then such proxies will talk to the objects in applications that have access to that resource and then get the result back.

Smart proxy:

“A smart reference is a replacement for a bare pointer that performs additional actions when an object is accessed”.

A smart proxy provides additional layer of security by interposing specific actions when the object is accessed. An example can be to check if the real object is locked before it is accessed to ensure that no other object can change it.

UML Diagram

Image courtesy: www.sourcemaking.com

Explanation:

  1. Both the Proxy and the RealSubject implement the Subject interface. This allows any client to treat the Proxy just like the RealSubject.
  2. The RealSubject is usually the object that does most of the real work; the Proxy controls access to it.
  3. The control may be needed if the Subject is running on a remote machine, if the Subjectis expensive to create in some way or if access to the subject needs to be protected in some way.
  4. The Proxy often instantiates or handle the creation of the RealSubject.
  5. The Proxy keeps a reference (pointer) to the Subject, so it can forward requests to the Subject when necessary.
  6. In some cases, the Proxy may be responsible for creating and destroying the RealSubject. Clients interact with the RealSubject through the Proxy.

Now let us try to understand this with some code. You can find the the code in my GitHub repository.

We shall consider an example of an Internet Proxy. Here, a client wishes to access internet but we shall add certain rules that will act as a firewall to enable restricted access to certain websites.

Image courtesy: www.wikipedia.com

First, we shall define our Internet interface.

public interface Internet {
void connectToUrl(String url) throws Exception;
}
view raw Internet.java hosted with ❤ by GitHub

Now we shall define our actual internet class (Real Subject)

public class ActualInternet implements Internet {
@Override
public void connectToUrl(String url) {
System.out.println("Making connection to: " + url);
}
}
view raw ActualInternet.java hosted with ❤ by GitHub

The Proxy class will implement the same Internet interface and add some additional rules that will mock the real internet.

import java.util.ArrayList;
import java.util.List;
public class ProxyInternet implements Internet {
private List<String> restrictedUrls;
private ActualInternet actualInternet;
public ProxyInternet() {
createRestrictedUrlList();
}
private void createRestrictedUrlList() {
restrictedUrls = new ArrayList<>();
restrictedUrls.add("www.facebook.com");
restrictedUrls.add("www.twitter.com");
restrictedUrls.add("www.youtube.com");
}
@Override
public void connectToUrl(String url) throws Exception {
//Example of Protection Proxy
//The proxy object makes some condition checks to act as a firewall
if (restrictedUrls.contains(url)) {
throw new Exception("Access Denied.\n" + url + " is a restricted url");
} else {
//Example of Virtual Proxy
//The proxy object offloads multiple heavy object creations to a single time
//Instantiates the real object when client requests for it the first time
if (actualInternet == null) {
actualInternet = new ActualInternet();
}
actualInternet.connectToUrl(url);
}
}
}
view raw ProxyInternet.java hosted with ❤ by GitHub

Finally, we will write our client code that will try to access certain websites

public class ProxyPatternMain {
public static void main(String[] args) {
Internet internet = new ProxyInternet();
try {
internet.connectToUrl("www.google.com");
internet.connectToUrl("www.facebook.com");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}

The expected output of the code is:

Making connection to: www.google.com

Access Denied.
www.facebook.com is a restricted url

Benefits:

  • Increased security.
  • Increased performance of the application. (This pattern avoids duplication of objects which might be huge size and memory intensive)
  • The remote proxy also ensures about security by installing the local code proxy (stub) in the client machine and then accessing the server with help of the remote code.

Drawbacks/Consequences:

This pattern introduces another layer of abstraction which sometimes may be an issue if the RealSubject code is accessed by the clients directly and some of them might access the Proxy classes. 

This might cause disparate behaviour.

Additional:

There are few differences between the related patterns. Like Adapter pattern gives a different interface to its subject, while Proxy patterns provide the same interface from the original object but the decorator provides an enhanced interface. Decorator pattern adds additional behaviour at runtime.

Please follow and like:

Leave a Reply