My Octopress Blog

A blogging framework for hackers.

Boiler Plate Code and Closures in Java

While working on a project recently, I ran into the following code:

public SomethingFromDatabase getSomethingFromDatabase(){
Element element = getDataFromCache();
return (SomethingFromDatabase)element.getValue();
}

private Element getDataFromCache(){
Element element = cache.get(KEY);
if(element == null){
element = new Element(KEY, dao.getSomethingFromDatabase());
cache.put(element);
}
return element;
}
Assuming cache is an instance of net.sf.Ehcache and the dao is your run of the mill Dao.

There’s some obvious problems with this code, the one that stood out the most to me is the boilerplate code. The solution I used to solve the problem, which is common, is to use closures:

public T get(String cacheKey, CacheDataClosure closure){
Element element = cache.get(cacheKey);
@SuppressWarnings("unchecked")
T cachedObject = element == null ? null : (T) element.getValue();
if(cachedObject == null){
cachedObject = closure.getData();
cache.put(new Element(cacheKey, cachedObject));
}
return cachedObject;
}

public interface CacheDataClosure {
T getData();
}
A similar approach is used by Spring in it’s *Template classes. Refactoring the original code to use the Facade, would look something like:

private Foo getDataFromCache(){
return cacheFacade.get(KEY, new CacheDataClosure(){
Foo getData(){ return dao.getFooFromDatabase(); }
});
}
I’m sure to some people reading this blog, the solution seems obvious, and almost not worth mentioning. However, over the years I have seen many interesting solutions to the same problem, especially in the database world, but elsewhere as well. You would be surprised how many people solve this problem with inheritance by instinct. Even those who have used frameworks that require a closure in certain scenarios, don’t necessarily think about what it is they’re using, and don’t think to use it when a problem arises later. Despite the fact that closures are ugly in Java, they are still the best solution for allowing for separation of concerns in a lot of scenarios, and reducing boilerplate code.

Comments

Lucas Ward
Thanks for pointing that out. I hadn't seen it before. I'm still not sure that I get it though, as I don't see a way for someone to define how the cache is refreshed, which is the main problem I had with the original code. When the cache is stale, you have to populate it yourself, and it's all boilerplate. As a user of ehcache, all I really want to tell them is how to get my data. Unless I'm missing something when looking at the Javadoc? (Which is highly likely)

I do think from looking at it that I may need to go back and think about concurrency. I haven't looked at the ehcache implementation, but I assumed it blocked. I was simply refactoring the earlier boiletplate code.
David Dossot
You could also consider using EHCache's SelfPopulatingCache construct (granted it's cache specific while your approach is generic).