On Oct 26, 2009, at 9:59 AM, Gili Tzabari wrote:
> > Stuart McCulloch wrote: >> 2009/10/26 Gili Tzabari <[email protected] >> <mailto:[email protected]>> >> >> ... but in practice, how often does that actually happen? >> It >> sounds to >> me like dependency injection is mostly about testability, not code >> reuse, and to that end ClassLoaders are actually less complex >> than all >> the hoopla that Guice does under the hood (hint: Guice uses ASM >> which >> uses bytecode rewriting and possibly even custom ClassLoaders). >> >> Just wondering, have you read >> http://martinfowler.com/articles/injection.html ? >> >> Ironically I've found DI helps me avoid being tied to specific APIs >> (case in point, OSGi services) >> because I can isolate their use in binding modules and providers, >> rather >> than in the code itself. >> >> And so far DI + services has definitely been good for my users :) > > > Okay, I overlooked the "service locator" aspect of DI. Thing is, how > often do you need this sort of thing? For example, if you're writing > Google Collections, how many of your classes are "services" and need > to > be plugable? Very few if any at all. This reminds me of the new > trend of > creating an interface for every class in the API even if there is (and > ever will be) only one concrete implementation. Interfaces and DI have > their uses, but applying them everywhere sounds overkill. I think the Google Collections example might be the worse example to pick from. Those are primarily data structure classes and don't have much business logic or "service" logic in them. Plus, the trend of using Interfaces for everything, even when there is only one implementation is actually quite old. I think most folks started really doing a lot of that in the 90s. I started doing it around 98. If you've read all the papers and articles on injection on the web, you'll have a good understanding for how important it is to code to interfaces and decouple things. One of my second favorite reasons to use a DI framework is refactoring. Let's say I have a class like this: public class MyAction { private final MyService service; @Inject public MyAction(MyService service) { this.service = service; } } public interface MyService { void doSomethingCool(); } public class MyServiceImpl implements MyService { public void doSomethingCool() { ... } } Guice will wire this up nicely whenever I need an instance of MyAction. Let's say MyService is being used by 20 or 30 other classes across a 3 different projects. As long as everyone is using MyService and NOT MyServiceImpl, I can refactor the internals of MyServiceImpl pretty much however I want as long as I maintain the contract of the interface. I can also change MyServiceImpl to have a bunch of new dependencies like this: public class MyServiceImpl implements MyService { private final MyDep1 dep1; private final MyDep2 dep2; private final MyDep3 dep3; @Inject public MyServiceImpl(MyDep1 dep1, MyDep2 dep2, MyDep3 dep3) { ... } public void doSomethingCool() { ... } } By using Guice I no longer have to go back and refactor those 20 to 30 other classes because they are all using the MyService interface and it is Guice's job to figure out the correct implementation of that interface and wire it up. Therefore, Guice will happily create my new version of MyServiceImpl and inject all of its dependencies automatically. -bp --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
