Have used the technique before as well, especially good when designing an API for others to use - it effectively renders documentation pointless. :) My usage was influenced by Wicket, which also goes far in assisting the developer when it comes to chaining properties like converters, validators etc. Knowing Dick is also using Wicket, I wonder if he was influenced by it too?!
/Casper On Nov 23, 4:03 pm, Dick Wall <[email protected]> wrote: > Hi, thanks for the interest. Here is the example builder I used in its > entirety: > > // The builder DSL > public interface SnpIdChromBothAllelesOnly { > public SnpDetail withOddsRatios(Map<Genotype, Double> > oddsRatios); > } > > public interface SnpIdChromRiskOnly { > public SnpIdChromBothAllelesOnly withNonRiskAllele(char > nonRisk); > } > > public interface SnpIdChromOnly { > public SnpIdChromRiskOnly withRiskAllele(char risk); > } > > public interface SnpIdOnly { > public SnpIdChromOnly withChromosome(String chrom); > } > > public static SnpIdOnly buildForId(String rsId) { > return (new Builder()).newFor(rsId); > } > > public static class Builder implements SnpIdOnly, SnpIdChromOnly, > SnpIdChromRiskOnly, SnpIdChromBothAllelesOnly { > > private String rsId; > private String chrom; > private char riskAllele; > private char nonRiskAllele; > > public SnpIdOnly newFor(String rsId) { > this.rsId = rsId; > return this; > } > > public SnpIdChromOnly withChromosome(String chrom) { > this.chrom = chrom; > return this; > } > > public SnpIdChromRiskOnly withRiskAllele(char risk) { > this.riskAllele = risk; > return this; > } > > public SnpIdChromBothAllelesOnly withNonRiskAllele(char > nonRisk) { > this.nonRiskAllele = nonRisk; > return this; > } > > public SnpDetail withOddsRatios(Map<Genotype, Double> > oddsRatios) { > return new SnpDetail(rsId, chrom, riskAllele, > nonRiskAllele, oddsRatios); > } > } > > It is, as mentioned previously, a wall of boilerplate (so much of Java > is), but this is still a neat pattern worth mentioning. In particular, > it uses different interfaces, each with a single method, returned from > each builder method, to lead you through the creation of the object. > This idea could be extended, for example if you needed either one > thing or another but not both, at some point you would return the > builder cast as an interface that offered only two methods, each of > which returning a different interface view of the builder, etc. > > The technique is overkill in this case, but if you have a DSL that is > intended to be used in a very controlled way and also is heavily used, > it starts to make more sense, since you can enforce object creation in > a way that you can only get the real object back once you have > satisfied all of the dependencies. > > The point of the talk was to mention that default and named parameters > largely eliminate the need for this kind of builder (although if you > really want to control everything about it, this same technique can be > used in Scala and other languages too). > > Cheers > > Dick > > On Nov 21, 12:33 pm, Jesper de Jong <[email protected]> wrote: > > > Thanks for the replies. Yes, Dick's builder pattern indeed had the > > fluent interface style, like FEST has. I'll have a look at how it's > > done in FEST. > > > Jesper > > > On 21 nov, 11:45, Moandji Ezana <[email protected]> wrote: > > > > On Sat, Nov 21, 2009 at 2:11 AM, Reinier Zwitserloot > > > <[email protected]>wrote: > > > > > This sounds like an interesting idea > > > > I've never seen before, and it also sounds like a massive wall of > > > > boilerplate. > > > > Entirely true. Again, check out > > > FEST-Reflect<http://fest.easytesting.org/reflect/> for > > > an example of how practical it is to use, and how impractical it is to > > > write. > > > > Moandji -- You received this message because you are subscribed to the Google Groups "The Java Posse" 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/javaposse?hl=.
