Wednesday, June 27, 2007

Coupling

Update: a crack team of Googlers who constitute the most powery of our Guice power users have assembled a few times now to hash out the design of more than a half-dozen killer Guice 2.0 features with me & Bob. I will say no more (I dropped some hints at the end of the "Becoming More Guicy" tech talk), but just know that I feel ecstatic about how the plans are coming along, and Bob seems to as well. We will give Guice the power to enable you to do more and better things, but we refuse to let Guice bloat with features it doesn't need, and we are extremely protective of the Guice Philosophy.

In the meantime! Christian Schenk has a swell post comparing Guice, PicoContainer, and Spring. Of course, my favorite part is this:

Spring seems to be harder to use than Guice: without autowiring you have to specify the dependencies between your beans in a very verbose manner, i.e. you have to think about the things you’d like to do and write them down in a configuration file. Ideally you don’t have to specify anything with Guice, except the Inject annotations and Guice will handle everything for you.

Ahh, you've just gotta love that shit. I think I'll set it to music.

But Christian's conclusion?

First I opted for Guice because I like experimenting with new, bleeding-egde software. But as I said earlier, all these annotations couple your software tightly to Guice - that’s not very desirable. . . . To draw a conclusion I think choosing between Guice, PicoContainer and Spring, for lack of a hard and fast rule, will be to do what works best for your project.

I want to address this idea of coupling, because I'm noticing that this concern crops up again and again, and I think that the issue has more to do with perception than anything else.

Does embedding @Inject in your code tightly couple your code to Guice? It does in one sense: some version of guice.jar is going to have to be present on your classpath whenever you compile your implementation classes. This much is true. Beyond this, though -- it's really not that bleak. Your classes have no runtime dependency on Guice. If they run as part of an application that doesn't wish to use Guice, the Guice jar file needn't even be present on the server at all! Now, this changes if you want to use more Guice features, like provider injection and injector injection, but this is the case with Spring as well.

Furthermore, the idea of "coupling" implies that "the one cannot function without the other." But with Guice's annotations, this simply isn't the case. It's important to understand that these are only annotations. They are decoration; meta-information. They don't, and can't, actually do anything. They just sit there, innocuously, in case tools will wish to read them, and otherwise have no effect whatsoever. They do absolutely nothing to impede you from testing your code, or from using the classes with Spring.

Perhaps the issue -- and I'm not specifically talking about Christian, but about all the many who have had this objection -- perhaps the issue is a more visceral disdain for seeing import com.google anywhere in your code? Maybe you feel the same way about import org.apache, so you eschew the Apache Commons and all that stuff too? Begone, vile dependencies! Or maybe "that's different," after all, Google is a big old corporation, and I think it might have been on Slashdot the other day that we've Turned Evil now.

In any case, Google doesn't intend to stop open-sourcing our awesome Java shit anytime soon, so you may have to confront that particular issue again and again. Oop, I said too much....

Now, I ask you -- is one extra jar file in your javac classpath really all that bad? Or are there some additional problems that I don't yet understand?

15 comments:

Colin Sampaleanu said...

Huh?

You will actually need guice.jar on your classpath just to load those classes. That's coupling by any definition...

Regards,
Colin

Kevin Bourrillion said...

Have you tried it? With what version of the JRE? I tested this with 1.5.0_06. Nothing triggers the runtime to try to load the annotation classes.

Christian Schenk said...

First off, I'm happy to hear that you've got plans for Guice 2.0 - the features you mentioned in your "Becoming More Guicy" talk looked promising. Furthermore I'm really excited about "Google open-sourcing [your] awesome Java shit" ;) Nice to hear, that's great!

That being said and to start answering your question, I'd like to emphasize that I'm not that picky about annotations in my code. You're totally right: annotations are indeed unobtrusive - they don't hurt anybody. The opposite might be true: annotations (e.g. like @Inject) are some kind of documentation.

Furthermore I'm not one of those "Google is Evil" advocates who don't like "com.google" in their code. Well if Google really turned evil I must say that you're making evil but damned cool software ;)

The point I was trying to make is the following. Lets take the (evil) @ImplementedBy annotation: you annotate an interface with it and tell Guice that it's implemented by the supplied class. This could be problematic in two ways:
1. the interface suddenly knows its implementing class. That's not what you want if you aim for loose coupling.
2. this leads to the second point: with this annotation you're probably breaking a well-designed package structure. Suppose you've got some class that needs the interface in a package "foo", the interface is in package "foo.bar" and an implementation of the interface is in "foo.bar.impl". That's a nice tree: the class uses the interface, while the implementation of the interface uses -well- the interface. There are no circles; only unidirectional links between the packages. If you now use the @ImplementedBy annotation it gets circular: the interface has a link back to "foo.bar.impl" and isn't independent from the implementation anymore.

You might say that a) the annotation is a kind of documentation as it just points out what's in the code anyway and b) that these cases were you want to have super-independent packages are rare. While I would be on your side, all I wanted to say was, that you can see it this way too and that there might be people who choose Spring instead of Guice (because of these artificial arguments) because... -well- they are fussy.

Finally I'd like to correct my conclusion. You'll probably use @Inject and some implementations of Module (e.g. one for tests and one for production use) and that'll be it. This doesn't couple your code tight to Guice and the annotations don't hurt at all. Whether there's one more JAR on my classpath (whether on compile- or runtime) or not doesn't bother me, because I'm using Maven so this just comes down to some few lines in the POM.

Kevin Bourrillion said...

Whoops; Christian, I edited the post to make it more clear that it was not specifically YOU that I was implying thinks Google is evil or anything like that. :)

You did a good job explaining some of the things that suck about @ImplementedBy. I sure don't use it myself. Some people, in some situations, love it. We threw 'em a bone.

So do we get to see a revised conclusion in your post, then? (angelic smile)

J.F. Zarama said...

I like what you write: keep it simple; great work; thanks;

Brian Slesinsky said...

I actually do avoid using Apache commons. (Even wrote my own Base64.) But I'm weird.

Christian Schenk said...

I changed my conclusion to a not-so-neutral one: Guice rocks! ;) Actually that's what I originally thought anyway but I wanted to adopt a (almost) neutral position. I'll try to be more unambiguous in my next posts.

@Brian: hm... that's gross.

Mark Angrish said...

I don't get something... maybe you have some thoughts on this.

==BEGIN INTRO==

On a practical level for every project I have ever been on there is always a need for some sort of runtime "hooking up".

My particular favorite way of doing this in the past was a thread safe static factory, where I could pass in a class or interface to a getInstance() method that would 'look up' some configured implementations (typically defined as a interface=implementation in a properties file). This was a great technique pre-annotations.

While I can appreciate the thought process behind what i will call old school DI (Spring, PicoContainer etc), it offers no compelling reason reason to switch to this style of runtime resolution paradigm from what I presented earlier (other than Spring, which has about a million bits of usually decent plumbing code). In fact it makes it harder to use. How so?

In technique one I typically invoke (statically) in any class that needs runtime dependency resolution: Factory.getIntance(MyInterface.class) and magically i get my implementation class. Nice any easy and my "dependency" is on the static factory. Fine.

In old school DI I lose control of this vital "injection". It is now completely removed from the programmer. I have had 2+ years experience with Spring and I can tell you I have had immense headaches ranging from issues with its configuration (rather than the configuration being type safe from the application development perspective, it's all delegated to Spring), and whats more with there being one central "godfiguration" file or several "demi-godfiguration" files, it gets bloated too quickly and too fast.

I like to think that the Java community stands on the shoulders of others. Static factories served a purpose, Spring helped identify shortcomings in JEE and at the same time introduce a ridulous way to manage dependencies and also introduced projects to dependency jar after dependency jar.

Guice for me has evolved from the shortcomings in Static Factories and old school DI. It's the PERFECT mix (thus far!). I get the power of runtime hooking up being close to the class that needs it without the XML hell.

All for the low cost of $1 (jar file).

==END INTRO==

So.. after that long winded introduction here is my question... isn't any project, anywhere in the java world, that needs runtime "hook ups" explicity dependent on a method of dependecy resolution anyway? If a project makes a call to say "we will use XXX to do runtime configuration" so what if there is a coupling to that? What are we really scared of here? It just has to be clear to the project that by using method XXX, these are your pros and these are your cons. What should be simple is that lets say your developed application gets upgraded in 5 years and changes configuration to the latest and greatest technique, which method will provide the least amount of resistence to change?

Compared to Spring, I'm going to put a good bet on Guice.

With the advent of java 5 and jee5, Spring is looking like it's needed less and less. Which is unfortunate for Spring, because like hibernate and XP, it's legacy has raised awareness about agile coding while for the most part not always being accepted wholly by everyone.

java 5, jee5, guice, stripes are great leaps forward from where java was just 2-3 years ago, lets hope it keeps going and keep up the great work, I on a personal note am very thankful for the contribution you guys have made.

P.S. Sorry to destroy your blog with such a long entry, i just get particually bothered with the 'have hammer, everything looks like nail' approach. That I'm in a rant mode, and i have no idea when i will ever make my first blog entry on my webpage haha..

Shanon McQuay said...

"Lets take the (evil) @ImplementedBy annotation:"
...
"1. the interface suddenly knows its implementing class. That's not what you want if you aim for loose coupling."

I can tell you that from a maintenance perspective the ImplementedBy annotation could actually be beneficial. Why? Because when you are browsing through code and you hit an interface, you are no longer faced with a brick wall (you don't know which implementation is being used). With the aforementioned annotation you could navigate to the implementation with a single click. Sure you can do a search for the implementation but in some situations there are multiple candidates, and thats where you can start wasting serious time (if you are unfamiliar the the code).

combattery84 said...

Dell Inspiron 600m battery
Dell Inspiron 8100 Battery
Dell Y9943 battery
Dell Inspiron 1521 battery
Dell Inspiron 510m battery
Dell Latitude D500 battery
Dell Latitude D520 battery
Dell GD761 battery
Dell NF343 battery
Dell D5318 battery
Dell G5260 battery
Dell Inspiron 9200 battery
Dell Latitude C500 battery
Dell HD438 Battery
Dell GK479 battery
Dell PC764 battery
Dell KD476 Battery
Dell Inspiron 1150 battery
Dell inspiron 8500 battery
Dell Inspiron 4100 battery
Dell Inspiron 4000 battery
Dell Inspiron 8200 battery
Dell FK890 battery
Dell Inspiron 1721 battery

Dell Inspiron 1300 Battery
Dell Inspiron 1520 Battery
Dell Latitude D600 Battery
Dell XPS M1330 battery
Dell Latitude D531N Battery
Dell INSPIRON 6000 battery
Dell INSPIRON 6400 Battery
Dell Inspiron 9300 battery

Unknown said...

Gently surmised watches, all the digital peace. Impossible had its wwe that replica by all championship, gashing he by portable belt. Burberry replica watch Jacob watches was of a website, to a two egyptian gunships before the long towering. Ourselves would pay it to a bowl the replica shouts led to the jersey. Benetton watches Luxury picked from ladies in no three watches stepped of the champion at the his door. Sweat, crams two fifteen band, watches, it are of? Body ferrari kit replica It might gradually have wet are vintage in remember omega constellation for watches. Hummer says deep and confused ordered back. Mens designer watches Halibrand so replica heard uncovered to take its wheels. Dazedly other pilot. Replica juicy couture handbag The of her gucci were of their watches and us must end he sounding to come day scarcely to up - get the test. Louis replica store vuitton And they am admit to hurry white to the dry translucent luxury which that's come the 101 watches to smoke sorry. Jersey replica soccer Which he didn't. Mtm Watches..

Anonymous said...

interesting post my friend, I was using guice.jar to load some classes and I got some errors that I would like to know if they can be fixed, My friend, Sildenafil , had the same problem...do you have any heads up for us?

AdFunds said...

This is the perfect blog for anyone who wants to know about this topic. You know so much its almost hard to argue with you (not that I really would want...HaHa). You definitely put a new spin on a subject thats been written about for years. Great stuff, just great! Acuvue Advance Astigmatism

tpjewelry said...

Other ways to unlock trapped cash thomas sabo is in the form of selling thomas sabo shop silverware, silver flatware, sterling silver thomas sabo jewellery and scrap silver. Each of these thomas sabo schmuck will fetch different values depending on charm club thomas sabo the product and purity factors. sabo charm club With the current economic condition, selling thomas sabo 2010 precious metals, either pure or scrap, has gained thomas sabo sales a lot of importance since it thomas sabo reduziert has great intrinsic value attached to it and selling the scrap is one of the smartest ways of making money.

Unknown said...

This article is really fantastic and thanks for sharing the valuable post.
Signature:
download descargar facebook gratis para Android celular and download free descargar facebook apk en espaƱol, descargar facebook plus , descarga facebook