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.

9 Comments:

Blogger Unknown said...

as well as a large number of inner classes per top level class, ;-). I also have a habit of using inner classes to reduce the clutter at the top level that is subject to greater change internally but I think you have out done me in some cases within the Guice codebase.

3:31 AM  
Blogger Bob said...

Ha ha. Think of them as Poor Man's Superpackages--it's a great way to group related classes together without exposing them in your API. ;)

9:01 AM  
Blogger Sony Mathew said...

For the very reasons you mention I had created Context IoC during the early days of Spring fever. Google it. I need to write a newer version of the article - its pretty dated now.

Few Guice Gripes:

(1)
Not fully Type safe:
binder.bind(Service.class)
.to(ServiceImpl.class)
ServiceImpl not required to implement Service interface at compile time.

(2)
Distinguishing dependency implementations with Annotations - i imagine creates a clutter of Guice specific annotations.

Context IoC provides complete type- safety with unbounded flexibility and unit testability and doesn't require annotations (but could be used for added power).

12:01 PM  
Blogger Bob said...

Sony, I do remember that article.

(1) You are incorrect. bind(Service.class).to(ServiceImpl.class) will not even compile unless ServiceImpl implements Service.

(2) I think annotations result in a lot less clutter than your "context" interfaces.

In addition, you only need annotations a small percentage of the time, i.e. when the type alone can't uniquely identify a binding, and when you do have annotations, you often reuse them in various contexts.

12:53 PM  
Blogger Sony Mathew said...

Bob,

Sorry, didn't realize u had generic typing backing that call sequence. At first glance it doesn't appear that way.

I guess clutter is relative. To me Context interfaces form a clean separation of concerns and yet keeps it localized to the Class that owns that concern. Having annotations strewn about - i'm not so sure about - but i guess its all relative.

1:40 PM  
Blogger Bob said...

Sony, regarding the relativity of clutter, I'm speaking purely in terms of lines of code in your class and its test code. I'm quite certain Guice requires a lot less.

2:22 PM  
Blogger imsticking said...

Bob, care to share any of your future plans for Guice with us? :o)

2:01 AM  
Blogger Bob said...

We keep everything in our issue tracker: http://code.google.com/p/google-guice/issues/list

8:26 AM  
Blogger parz said...

Guice is great and dependency injection frameworks are here to stay, but why settle for frameworks. Object oriented programming has revolutionized the way we construct software and I am convinced that an Object Oriented Dependency Injection language will do the same.

I created a language/container back in 2006 but due to lack of real world experience it has many flaws (see jooc.org). What I have come to realize since then is the importance of OODI contracts. OO contracts make DI typesafe and much more.

Have you looked at OODI? Do you know of a project of this type to join?

4:36 AM  

Post a Comment

<< Home