Thursday, September 08, 2005

something remotely like an actual use for DynamicDelegator

Closer than our barking vehicle example, but still a toy. But hopefully you should be able to see the power of this thing. Without DynamicDecorator, the class below would have to provide an implementation of the entire COnnection interface, with all of it's methods except for close() just tunnelling straight through to the real connection. Something like this (but not exactly this) is why I wrote this kind of code for a real project at work.


/*
* StoopidDatabaseConnectionPool.java
*
* Created on September 8, 2005, 4:24 PM
*/
import java.util.*;
import java.sql.*;
/**
* Really simple example of how you might use DynamicDelegator.
*
* @author jRobertson
*/
public class StoopidDatabaseConnectionPool {

Collection pool = new HashSet();

public synchronized Connection getConnection() {
Connection con;
if( pool.isEmpty() ) {

// no connections already exist, so make one
con = reallyConnectToDatabase();

} else {
// get one from the pool
con = (Connection) pool.iterator().next();

// remove it so no one else can have it
pool.remove(con);
}

// wrap the connection with a proxy that will
// put the (real) connection back into the pool
// when the proxy is closed.
return (Connection) new PooledConnection(con).getProxy();

}


// named class, not anonymous, because of issues using
// reflection on local classes
public class PooledConnection extends DynamicDelegator {

public PooledConnection(Connection c) {
super(c);
}
public void close() {
pool.add(wrapped);
}

}

private Connection reallyConnectToDatabase() {
// not implemented for this silly example!
// if you want to try it, implement it yourself

// create a mock "Connection" that implements the
// Connection interface in the sense of being able
// to be assignable, but which does not actually
// implement any of the methods (they will throw exceptions).
// Another crazy use for InvocationChain.
InvocationChain chain = new InvocationChain();
chain.add(new Object() );
chain.addInterface(Connection.class);
return (Connection) chain.newProxyInstance();
}

public String toString() {
return "StoopidDatabaseConnectionPool: "+pool.size();
}

public int size() {
return pool.size();
}


}

Comments: