OSMIS Technical Specification

Architecture Overview

2.4 Virtual Proxy Pattern

According to the GoF, the intent of a proxy is to "provide a surrogate or place-holder for another object to control access to it". This is commonly used in a number of situations:

  1. Virtual proxies: used for lazy instantiation
  2. Remote proxies: used for remote method invocation (RMI) and the like
  3. Access proxies: used to perform security checks before allowing access to a sensitive object.

In this project, we will be using virtual proxies. What follows is a description of how these work.

Consider the following Java pseudo-code:

public class A
{
  private B b;
  private String s;
  void aMethod(); //uses b and s
}

public class B
{
  private int i;
  void bMethod(); //uses i
}

Assume that we would like to be able to get A from the database, and lazy-load B at a later stage. Since we can only interact with the classes by calling their methods, we don't really care about when the values of b,s and i are instantiated, only that the method calls work. The following is a solution to the problem:

public class AProxy
{
  A a;
  void aMethod()
  {
    if (a==null)
      createA(); //see note later for this method
  }
}

public class BProxy
{
  B b;
  void bMethod()
  {
    if (b==null)
      createB(); //see note later for this method
  }
}

Clearly, this is not transparent to a developer. To make it transparent, the developer must be able to access (from a typing point of view) AProxy in the same manner as he would access A. This requires the following modifications:

  1. Create an interface A, and an interface B
  2. Rename the original A class to something like AImpl, and B to BImpl
  3. Let AImpl, AProxy, BImpl, and BProxy implement A and B respectively.

The developer can now use his original code unchanged, always dealing with A and B.

Now, what about the createA and createB methods? Well, these are normal Java methods to instantiate the real A and B objects. They are totally implementation dependent. Assume we are trying to instantiate A and B from a database. Assume furthermore that BProxy (and associated classes) now looks like this:

public class BProxy
{
  B b;
  void bMethod()
  {
    if (b instanceof BReference)
      b=createB(); //see note later for this method
  }
}

public class BReference extends Reference implements B
{
  void bMethod()
  {
    throw new Exception("Not implemented");
  }
}

public class Reference
{
  int objectIdentifier;
}

Then, we could have the following createB() method:

public B createB()
{
  ...
  instantiate a B object from the database, based on the fact that we have
  a reference with an identifier.
  ...
  return BImpl
}

The bit between the ...'s can be done using either a helper class or in the code itself. Either way, if code is added to the system, existing classes do not need to be changed. Looking at createA in AProxy:

createA()
{
  ...
  b=new BReference(theDatabaseIDForB);
  ...
}

This is the only time we would use a reference rather then the real object in any other class (it may even be possible to get around this).

The whole reference thing is not strictly necessary, it could be implemented in the proxy class, We believe it is neater however. In fact, assuming we always use an int id as a primary key, we don't even need a BReference object, a Reference will do just fine. one could then do something like:

public class Proxy
{
  Reference r;
  boolean instantiated;
}

public class BProxy extends Proxy implements B
{
  B b;

  BProxy(Reference r)
  {
    super(r);
  }
  void bMethod()
  {
    if (!instantiated)
      createB();
    b.bMethod();
  }
}
and have the same initialisation code in A as above.

So, what does this all mean? It means that on the Java side, all we have are model objects. Each model object, either when defining the proxy class, or via a helper class (similar to a factory class) knows how to perform all database operations on the object - create, commit, delete, and possibly search (which should almost definitely occur in a helper class).

Further references for virtual proxies can be found in the attached handout, as well as at http://www.javaworld.com/javaworld/jw-02-2002/jw-0222-designpatterns.html . Many other resources describing the virtual proxy pattern exist on the web.

  << Previous Up
Home
Next >>