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.

Reply via email to