Tuesday, October 16, 2007

Why Guice?

TheServerSide just posted a video interview they recorded in May shortly after the Guice 1.0 release. Since then, I've had ample time to chew over what I like so much about Guice and hone my thoughts on dependency injection in general.

Being a fan of plain old Java, before I wrote Guice, existing dependency injection frameworks were non-starters for me. I'd sooner write factories by hand than keep XML in sync with my classes or embed method names in strings. I mean, if you don't have type safety, all of that extra typing really is for naught, and you might as well switch to Ruby. Furthermore, a programmer shouldn't have to fire up a debugger or even think too hard in order to figure out what her code is doing. I felt the same way about mocking frameworks until EasyMock pioneered their extraordinarily typesafe approach.

Before Guice, I had to make the same up-front decision over and over: do I call a constructor directly, or do I write a factory and call it instead? If you start out calling a constructor and later decide that you need a factory, you have to go back and change all the callers. On the other hand, factories come at a cost: they clutter your API and result in a bunch of boilerplate code which you have to both write and maintain. In practice, if the only reason you need a factory is to enable testing, most programmers will forgo the factory, testing be damned.

Guice provides the best of both worlds and finally enables agile programming in Java. Injecting an object requires roughly the same amount of effort as calling a constructor. If you decide later on that you need more abstraction, write a factory and change your code in one place; there's no need to change all the callers. If you're providing code to someone else, give them a bunch of interfaces and a Guice module. They can test their code, you can change how you create objects to your heart's content without impacting your users, and your API will be smaller to boot. As you can probably tell from Guice, I love small, interface-heavy APIs.