OK. I read the article. Ugh. I advise you to keep Uncle Bob as far from your code as possible. He has some fundamental understandings of DI that could only stem from:
1) Never watching a Guice talk 2) Barely skimming Guice's documentation 3) Not writing real code for a long time First, he clearly thinks we use Injector everywhere in our code; most of his bad advise is based on that false assumption. Everyone here knows that using Injector is equivalent to using reflection. It would be like accessing ClassLoader directly in your code. He doesn't get the idea of bootstrapping, and I don't think he understands the concept of objects being recursively injected. What's funny is that he, a purported testing expert, suggests that you use static instead. He says, "you think the injector is not a global? You think BillingService.class is not a global? There will always be globals to deal with." Guice users know that there don't always have to "be globals to deal with" outside of your code's entry point. Uncle Bob doesn't know what he's missing out on. Second, his approach doesn't scale. Instead of: bind(TransactionLog.class).to(DatabaseTransactionLog.class); He suggests: TransactionLog tl = new DatabaseTransactionLog(); He says, "Why is this worse? It seems to me it’s better." I say, what happens when you inject TransactionLog somewhere else? Do you say "new DatabaseTransactionLog()" again? With Guice you do nothing. What happens when you inject TransactionLog 100 times? Do you write "new DatabaseTransactionLog()" 100 times? With Guice, you write "bind(TransactionLog.class).to(DatabaseTransactionLog.class)" once. Uncle Bob's solution is O(N) for a given type. Guice is O(1). Bob doesn't realize this because N=1 in his example. Uncle Bob says, "I don’t want to have to hunt for the particular bind call for the Zappleinterface when I’m looking at some module." I say you shouldn't have to because Guice was designed with IDE support in mind. Now, someone asked why we require @Inject on constructors. First, we focus on readability over writability. You write @Inject once, and it's there to help the next 100 people who read your code. Second, it prevents unintended automatic injections. For example, the fact that we call default constructors w/o @Inject already bites us. If you inject a String and forget the binding annotation, Guice will happily new up an empty string (String has a default constructor for some reason). Third, it tells Guice in a secure way that it's OK to override accessibility restrictions. For example, I believe most injectable constructors should be package private. Fourth, supporting annotation-less injection would make the rules more complicated. I think Guice is too complicated already. Thanks, Bob -- You received this message because you are subscribed to the Google Groups "google-guice" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.
