Alexandru V. Simonescu

Software Craftsmanship and Android Development

Proxy design pattern

The article you’re about to read is part of a bigger series about software design patterns implemented on languages using the JVM, mostly Java. In this one the Proxy pattern is presented.

Table of contents

Description

Gang of Four definition: Provide a surrogate or placeholder for another object to control access to it.

The Proxy pattern can be used to add an extra level of indirection to suport a more intelligent access to a class, or to add a wrapper to protect the real class from undue complexity.

Types of Proxies:

  • Virtual Proxy: is a placeholder for “expensive to create” objects.
  • Remote Proxy: will hide the original object who lives in a different address space.
  • Protection Proxy: generally deal with different access rights.
  • Smart Reference Proxy: provides some additional actions when the original object is accessed. Like counting the number of references to the real object. Also a lock to the original object can be made from the Proxy, to ensure when accessed no other object can change it.

Use cases

Some times we have heavy objects in our systems, like for example an data access object, whose instantiation is expensive and take time. We may not want to create that heavy object in case we won’t use it. An basic use case will be wrapping that class into a Proxy and instantiate the original class only when needed or accessed. So the real object will be instantied only on user requests and control will be delegated to real object.

Pros

  • Provide intelligent or optimized access to heavy resources.
  • Simplify API ussage by creating proxy wrappers.
  • Add actions when accessing existing code.

Cons

  • Can be used to hide implementation details of a concrete class, but the concrete class may be still directly instantiated.

Implementation

Heavy work wrapping

In this example we will wrap a heavy work class, in a real world example, this class will open some network sockets, database connection or start some daemon threads.

public class HeavyWorkProxyShould {

  @Test
  public void not_create_real_object_until_proxy_method_called() throws Exception {
    HeavyWorkProxy heavyWorkProxy = new HeavyWorkProxy();

    assertNull(heavyWorkProxy.heavyWork);
  }

  @Test
  public void create_real_heavy_object_when_proxy_method_called() throws Exception {
    HeavyWorkProxy heavyWorkProxy = new HeavyWorkProxy();

    heavyWorkProxy.run();

    assertNotNull(heavyWorkProxy.heavyWork);
  }
}

This time the implementation will be as easy as creating a lazy instantiation field.

public class HeavyWorkProxy implements Runnable {

  HeavyWork heavyWork;

  @Override public void run() {
    if (heavyWork == null) {
      heavyWork = new HeavyWork();
    }

    heavyWork.run();
  }
}

Simplify code or API

Another ussage of the Proxy patterns is a wrapping class for simplifying the ussage for some API. A simple code for retrieving a website HTML can be the following:

public class ProxyMain {
  public static void main(String[] args) {

    String hostname = "http://www.google.com";
    String content;
    URLConnection connection;
    try {
      connection = new URL(hostname).openConnection();
      Scanner scanner = new Scanner(connection.getInputStream());
      scanner.useDelimiter("\\Z");
      content = scanner.next();
      System.out.println(content);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

And it works. But a proxy wrapper can be created to simplify the HTML retrieval.

public class ProxyMain {
  public static void main(String[] args) {

    String html = new HtmlFromHostname().retrieve("http://www.google.com");
    System.out.println(html);
  }
}

All the code from this post can be downloaded from the Design Patterns repository.

Bibliography