The Proxy pattern creates an interface giving access to a resource to hide any underlying-complexity as well as to add improvements of the underlying code. The proxy interface looks like the interface it “caches.”
Let’s think about a query object we want to use to query a database. It is great to log any request for debugging purpose.
public class SimpleQuery<T> implements Query<T> {
public T findBy(String id) {
// connect to database, query, etc.
return db.query(sql);
}
public void insert(T object) {
// connect to database, create id, etc.
db.insert(sql);
}
}
We are going to proxy this with inheritance. It is possible to implement this pattern with other techniques such as composition (having a reference of the object to proxy), or introspection if we want the proxy to be dynamic (done at runtime).
public class ProxyQuery<T> extends SimpleQuery<T> {
private Logger logger = ... // whatever framework you want to use
public T findBy(String id) {
// connect to database, query, etc.
String sql = "select * from table where id="+id;
logger.debug(sql);
return db.query(sql);
}
public void insert(T object) {
// connect to database, create id, etc.
String sql = "insert into table (id, value) values ("+id+","+object+")";
logger.debug(sql);
db.insert(object);
}
}
And that’s all! Of course proxies can be much more complex. It can be used to call a remote object. It can be used to use a cache, etc.
Now you may wonder: what is the difference between the proxy pattern and the decorator pattern?
- The proxy pattern provides an identical interface while the decorator provides an enhanced interface.
- The decorator usually aggregates (composition) what it is decorating. The proxy does not have to work that way.
- Proxy might interface an object that has not been created yet. For example, you may want to stack up / validate information before creating the actual object for performance sake.