On a slightly unrelated note, I take issue with the insinuation that
Functional languages do not do the strategy pattern well. I'd say higher
order programming achieves the same goal, and somewhat more elegantly than
the strategy pattern.

Dhanji.

On Thu, Mar 18, 2010 at 2:57 PM, Jason Felice <[email protected]>wrote:

> 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]<google-guice%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/google-guice?hl=en.
>

-- 
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