Thursday, April 17, 2008

Inversion of Scoped Objects

In C++ it was common to use paradigms known as RRID (Resource Release is Destruction) or RAII (Resource Allocation is Initialization). The basic premise of these are you want to be guaranteed a section of code is execute upon exiting or entering a block respectively.

They usually look like the following:


template<typename T>
class scopedLock {
T& m_lock;
public:
ScopedLock(T& lock) : m_lock(lock) { lock.acquire(); }
~ScopedLock() { m_lock.release(); }
};

//Later
void MyClass::doSomethingSyncrhonized() {
ScopedLock scopeLock(mutex);

//Do syncrhonized code
}



You're guaraneteed that when doSomethingSynchronized returns, the ScopedLock destructor is called, therefore releasing the lock. This is regardless of how you leave the scope.

Spring has done an "inversion" of this principle for making code simpler. Let's look at JdbcTemplate objects. I want to open a connection, perform some query, map the results into an object and return a list of that object ensuring my connection is closed at the end. Here's the code:



List<MyStuff> list = jdbcTemplate.query(
"select stuff with parameters ? and ?",
new Object[]{param1, param2},
new RowMapper() {
Object mapRow(ResultSet rs) {
return new MyStuff(rs.getString("Important"), rs.getString("Stuff"));
}
});



If you notice, the pattern is inverted. I never specify anything about the connection object. The jdbcTemplate takes care of that for me. I place all my code inside the anonymous inner class that is an instance of RowMapper (Think Anonymous Inner Class ~= Closure). No where in the "closure" am I catching exception OR manipulating the connection. JdbcTemplate is ensuring that code happens before and after that scope, similarly to how C++ ScopedObjects work, but with a complete inversion in thought.

Scala tops Java by introducing real first-class functions and amazing abilites. Let's look at the Future class in Scala (pulled from Scala-By-Example):


def future[A](p: => A): Unit => A = {
val result = new SyncVar[A]
fork { result.set(p) }
(() => result.get)
}


If you notice, a "future" creates a synchronized variable store (like an atomic variable) called result. Future then forks and executes the passed in function in the fork (syntax fork { stuffToDo }). Much more elegant way of performing things before and after a method call. Scala can also pool threads as the client code isn't specifically starting/stopping threads at this point.


Addendum


As I was just re-reading the Scala section, I realize how lame my conclusions are. I plan to make some really good sample code when I got some more time. Unfortunately when I was writing the entry, the baby woke up. Anyway, the thing I was really trying to point out is that the Inversion of Scoped Objects creates the idea of "New Language Features." The "fork" command could actually just be a static method that takes in a closure and executes it on a separate thread. Anyone with some Scala/Java knowledge could write this code and make sure it calls the closure in the middle. I read a Ted Neward post about using Scala to create a "safe_execution" language feature in a similar manner. This function would merely call a closure within a try catch and log exceptions. This can be really powerful, especially in environments where you don't have control over all the code being executed (Eclipse Plugins/RCP is a good example where a "safe_logging_execute" would be helpful). Anyway, I may go in and clean up the scala bit to be more coherent when I get back from Chicago.

0 comments: