proxy design pattern in java with real world example

Proxy Pattern is a structural design pattern which is used to create a representative object that controls access to another object, which may be remote, expensive to create, or in need of securing.

There are many variations of the Proxy Pattern and the variations typically revolve around the way the proxy controls the access. Here are a few ways proxies control access like a remote proxy controls access to a remote object and a virtual proxy controls access to a resource that is expensive to create and a protection proxy controls access to a resource based on access rights so on. The proxy design pattern is good when we want to delegate some expensive operations to other classes, do operations lazily, and thus make our applications more efficient.

Lets check the class diagram for this pattern

The proxy design pattern is another example of a wrapper. First we have a Subject, which provides an interface for the RealSubject and the Proxy. By implementing the same interface, the Proxy can be substituted for the RealSubject anywhere it occurs.The RealSubject is the object that does the real work. It’s the object that the Proxy represents and controls access to. The Proxy holds a reference to the RealSubject. In some cases, the Proxy may be responsible for creating and destroying the RealSubject. Clients interact with the RealSubject through the Proxy.

Because the Proxy and RealSubject implement the same interface that is Subject, the Proxy can be substituted anywhere the subject can be used. The Proxy also controls access to the RealSubject; this control may be needed if the Subject is running on a remote machine, if the Subject is expensive to create in some way or if access to the subject needs to be protected in some way.

Lets say we have to access the raw data from oracle db and lets assume this is a static data and we do not want to hit the database each time we need this data in our application. And also we are using a external api to access this data from oracle and the default behaviour is to hit the db every time the data is requested . Considering we have a static data we want to build something which will hit the db only the first time we request for the data and cache it, so that we can return the data from cached data instead of hitting the db each time.

Lets build a proxy to solve this.

First we have a QueryCommand, which provides an interface for the RealSubject and the Proxy. By implementing the same interface, the Proxy can be substituted for the RealSubject anywhere it occurs. We have a real object RawAggTableCommand and a proxy for this RawAggTableCommandProxy.The RawAggTableCommandProxy holds a reference to the RawAggTableCommand.

Lets code the QueryCommand


public abstract class QueryCommand {

abstract public <T extends Model> List<T> execute(Object[] parameters);
}


public class RawAggTableCommand extends QueryCommand {

private DbType dbtype;

public RawAggTableCommand(DbType dbtype) {
super();
this.dbtype = dbtype;
}

@SuppressWarnings("unchecked")
@Override
public List<RawMetric> execute(Object[] parameters) {
ConfigFile scriptFile = new ConfigFile(Constants.QUERY_RAWTABLE, FileType.script);
String script = scriptFile.getFileContent();
return dbtype.query(script, parameters, new RawMetricMapper());
}

}


public class RawAggTableCommandProxy extends QueryCommand {

private RawAggTableCommand rawCommand = new RawAggTableCommand(new Oracle());

private List<RawMetric> list = new ArrayList<RawMetric>();

public RawAggTableCommand getRawCommand() {
return rawCommand;
}

public void setRawCommand(RawAggTableCommand rawCommand) {
this.rawCommand = rawCommand;
}

public List<RawMetric> execute(Object[] parameters) {

if (list.size() == 0) {

return rawCommand.execute(parameters);
} else {
return list;
}

}

}

Lets code the test class. As we can see client will use the proxy instead of the real object to get the same result.


public class Test {

public static void main(String[] args) {

QueryCommand proxy = new RawAggTableCommandProxy();

List<RawMetric> list = proxy.execute(new Object[] { "parameter1", "parameter2" });

System.out.println(list.size());

}

}

Leave a Reply

Your email address will not be published. Required fields are marked *