A while ago, I wrote about how the modern, trendy dynamic languages (that are nothing like 1960s functional ones, honest) allow you to perform operations on collections without you having to do the messy business of iterating through the collection yourself. Now that the author of the multi-denominational gospel according to programmers has expressed a dislike for both trendy techniques and code reuse, I thought it would be a good time to revisit the topic.
The idea of achieving code reuse by generalising the outside of a repeated operation and calling a supplied function on the inside is called inversion of control. In the dynamic collection utilities, the outside is an iterative operation like traversing a list and removing items that fail a test, with the inside being the test itself. Something else that you may find more compelling is database access. If you program in Java, you have almost certainly written or seen this exact code:
try
{
}
{
}
{
}
finally
{
}
In fact, you’ve probably written or seen it dozens of times. Sometimes people forget to catch RuntimeException, and the missing rollback causes deadlock detection errors in random parts of the system. Sometimes they ignore any exception thrown when closing the connection, and sometimes they don’t, meaning you can lose information about the cause of an error.
If you apply the inversion of control pattern to this code, you get this:
{
}
{
}
The code to use this is:
try
{
}
{
}
ConnectionHandler and DbUtils are, of course, reusable. Inversion of control has more than halved the number of boilerplate lines, and most of the ones left over are a consequence of Java’s not being a dynamic language. More importantly, you have consistency – all database transactions are handled the same way.
The code above is far from complete – a way to set the transaction isolation level is required; a return value from handle might be useful; perhaps ConnectionHandler could declare a handleSqlException method; I would advise silently ignoring any exception on connection closure after an SQLException has been caught – but it’s a start. For more ideas, take a look at Apache’s DbUtils or the Spring Framework’s JdbcTemplate.
I think you need to add ); to the creation of your handle code in the "The code to use this is:" code block ... excellent introduction for the newbs (and unfortunately, many more experienced programmers).
Posted by: Steve Moyer | April 28, 2008 at 09:31 PM
Fixed.
Posted by: | April 28, 2008 at 10:22 PM