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.