Thursday, May 03, 2007

Guice, Spring, and Arid

I was reading this article on Arid POJOs on TSS today. Chris Richardson, the author of Arid, has a nice introduction to it. One thing I found amusing was the statement at the beginning
...an important benefit of using XML is that it completely decouples the components that are being assembled from the mechanism that is assembling them This is not true when using annotation-based dependency injection such as that provided by the Guice framework. Components that use those kinds of annotations are tightly coupled to the framework and are definitely not POJOs!
I've been known to make my own digs on Google frameworks, but sometimes you have to call out FUD when you see it. The POJO argument usually comes from the requirements of writing EJBs prior to EJB3. You had a lot of interfaces to implement, and some of these interfaces required a lot of methods (typically lifecycle callback methods) to implement. To be an EJB you had to look like an EJB to the container, hence all those interfaces and methods to implement. The term POJO came about because POJOs don't look like EJBs.

So it is ridiculous to somehow say that a class that uses a com.google.inject (or javax.ejb for that matter) Annotation is not a POJO. Can a POJO not have any Annotations? Can a POJO not reference third party packages? Better remove all your Jakarta commons import statements...

As for tightly coupling to a framework, I will concede that it is nice to be able to switch out your DI provider without having to change code. I guess that is one drawback of using Guice. The Guice solution of writing a Module class for doing all the wiring and thus isolate the dependency doesn't seem realistic. You could do the same thing in Spring: programmatically create your configuration and thus wire together your classes. Nobody does that though, they all use XML files or maybe auto-wiring.

So maybe Chris Richardson has a valid point here. Bob Lee and the Guice gang at Google make some strong arguments for switching to Guice from Spring. You have to change code to make that switch, and you'd have to change code again to switch back.

I think in many cases, it is worth the "pollution" of your code. The thing I like about EJB3 and Guice annotations is the explicit dependencies. I have to worry about not only writing code, but also about writing code that other developers can understand. I have to worry about the learning curve I create for new developers I hire. There is a lot of clarity in something like:

@ImplementedBy(MyClassImpl.class)
public interface MyClass { ... }

There is also a lot of clarity in seeing a unit test that creates a module to override the bindings to allow for mock versions of certain classes.

At Ludi Labs, we used Spring in just about every way it can be used. Sometimes we got a little carried away and patted ourselves on the back about how clever we were. Then we would bring on a new developer and they would struggle to figure what the heck was going on with our application. We would have to patiently walk them through some things until things started to click. I have a feeling that Guice would have made this less painful for new developers, though there were definitely things we did with Spring (especially using its AOP support in conjunction with DI) that I'm not sure you could do with Guice.

No comments: