I just posted this blog article: http://eraserhead.net/2010/03/creating-boilerplate-with-google-guice/
A note: While it seems to be a peculiar problem, I'm not slamming Guice, Guice is still a big net win for us! I post here for thoughts on this problem, and suggestions for solutions to it. Excerpt: There’s plenty of boilerplate that Guice removes, mostly in the “bean wiring” category, and this is good. Interestingly, there are areas in which I’ve found myself writing *more* boilerplate with Guice, and an instance of this is what I’d like to discuss today. I work with some people who have become thoroughly disgusted with OOP and advocate for functional style with immutable data types. I appreciate functional style with immutable data types, but I must say that the Strategy pattern <http://en.wikipedia.org/wiki/Strategy_pattern> is something OOP does well and not something that FP does nearly as well. I tend to use strategy pattern quite a bit in our XPay (and in our C++ product, DAS). One reason to prefer Strategy pattern to switch statements<http://c2.com/cgi/wiki?SwitchStatementsSmell>is to have a single point of control over *which* strategy implementation to use. This use case usually conjures itself into being in a Factory method pattern<http://en.wikipedia.org/wiki/Factory_method_pattern>which has the single switch statement which provides an instance of the concrete type based on input parameters. In Guice, you can inject a Provider<Foo> and Guice will automatically create a type that produces instances of Foo. This is useful for dependencies. So our factory ends up looking something like this: class FooFactory { private final Provider<TypeAFoo> typeAFooProvider; private final Provider<TypeBFoo> typeBFooProvider; private final Provider<TypeCAFoo> typeCAFooProvider; private final Provider<TypeCBFoo> typeCBFooProvider; private final Provider<TypeDFoo> typeDFooProvider; private final Provider<TypeEFoo> typeEFooProvider; @Inject public FooFactory( final Provider<TypeAFoo> typeAFooProvider, final Provider<TypeBFoo> typeBFooProvider, final Provider<TypeCAFoo> typeCAFooProvider, final Provider<TypeCBFoo> typeCBFooProvider, final Provider<TypeDFoo> typeDFooProvider, final Provider<TypeEFoo> typeEFooProvider ) { this.typeAFooProvider = typeAFooProvider; this.typeBFooProvider = typeBFooProvider; this.typeCAFooProvider = typeCAFooProvider; this.typeCBFooProvider = typeCBFooProvider; this.typeDFooProvider = typeDFooProvider; this.typeEFooProvider = typeEFooProvider; } public Foo get(char type, boolean inverted) { switch (type) { case 'A': return typeAFooProvider.get(); case 'B': return typeBFooProvider.get(); case 'C': if (inverted) return typeCAFooProvider.get(); else return typeCBFooProvider.get(); case 'D': return typeBFooProvider.get(); case 'E': return typeBFooProvider.get(); default: throw new FooFactoryException("Can't determine type."); } } }; Ugh! This is “better” boilerplate than the bean wiring before in that it hints that we might be able to concoct a general solution; however, I haven’t yet found it. One solution which I’ve rejected is the “injecting an injector” solution: class FooFactory { private final Injector injector; @Inject public FooFactory(final Injector injector) { this.injector = injector; } public Foo get(char type, boolean inverted) { switch (type) { case 'A': return injector.createInstance(TypeAFoo.class); case 'B': return injector.createInstance(TypeBFoo.class); case 'C': if (inverted) return injector.createInstance(TypeCAFoo.class); else return injector.createInstance(TypeCBFoo.class); case 'D': return injector.createInstance(TypeDFoo.class); case 'E': return injector.createInstance(TypeEFoo.class); default: throw new FooFactoryException("Can't determine type."); } } }; The reason I’ve rejected this approach is that it prevents Guice from checking the entire dependency graph at boot – Guice doesn’t know which types you are going to create with the injector, and this *has* to defeat a lot of it’s validation magic. -- 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.
