Code Scavenger’s Chronicles

venting steam….

Archive for May 2008

Builders

without comments

Prediction???
Factories are out; Builders are in.

Basis
Here is some “gyan” laced with content filched from Josh Bloch’s prezo on Builders in Javaone 06/07.

In the Builder pattern:-
• Builder constructor takes all required (manadatory) params
• One setter for each optional parameter
• Setters return the builder to allow for chaining
• One method to generate instance
• Pattern emulates named optional parameters!

Here is an example invocation/usage:-

NutritionFacts locoCola = new NutritionFacts.Builder(240, 8).sodium(30).
carbohydrate(28).build();


Here is the builder code for the example above:-

public class NutritionFacts {

    public static class Builder {
        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings = servings;
        }

        public Builder calories(int val) {
            calories = val; return this;
       }
       ... // 15 more setters

        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
    }

    private NutritionFacts(Builder builder) {
        <copy data from Builder to NutritionFacts>
    }
}

But writing a builder for each object gets oh so tedious every time. Cant we have something easier (read less code) Mr. Bloch?

Solution

Well, Robbie Vanbrabant has one. See BuilderBuilder.

For any object that you need to create a builder for; this is what you need to do:-

public class Example {
    private final String mandatory;
    private final int optional1;
    private final char optional2;

    private Example(ExampleBuilder builder, String mandatory) {
        this.mandatory = mandatory;
        this.optional1 = builder.getOptional1();
        this.optional2 = builder.getOptional2();
    }

    public interface ExampleBuilder extends Builder {
        ExampleBuilder optional1(int optional1);
        ExampleBuilder optional2(char optional2);
        int getOptional1();
        char getOptional2();
    }

    public static ExampleBuilder builder(final String mandatory) {
        return new BuilderFactory(BuilderType.SIMPLE_SETTER)
            .makeRisky(ExampleBuilder.class, Example.class, mandatory);
    }

    public String toString() {
        return new StringBuilder()
            .append(getClass().getName())
            .append(String.format("[optional1=%s, optional2=%s, mandatory=%s]",
                optional1, optional2, mandatory)).toString();
    }
}

And how do we use it?

Example.builder("Mandatory!").optional1(4).build();

Thats it!

No need to write the Builder code. Just write the interface for the Builder and you are ready to roll!

Well, how does this work?

Dissection

Remember Java Proxies and Reflection. Thats the magic behind it. See the code for BuilderFactory.

Notice how makeRisky() creates a callback handler BuilderCallback and passes it on to make(). Essentially make() creates a Proxy for Class V using an invocationhandler called BuilderInvocationHandler. BuilderInvocationHandler takes in the callback BuilderCallback as an argument.

As is mostly the case with invocationhandlers, the BuilderInvocationHandler creates a map backed storage for all the attributes of Class V, which is accessed whenever a set for an attribute is invoked via invoke(). Note that the set() for an attribute in this pattern always returns the Builder T. In the case where build() is called, it delegates the call to call() method on the callback handler BuilderCallback which returns an object of Class V.

So, essentially the trick works flawlessly with a sprinkling of reflection and callbacks. Cool!

NOTE: Robbie got this done last year. I just happened to stumble over it now! :(

JEDI Moral: Less YouTube Must Watch This Year

Written by shakhan

May 8, 2008 at 10:30 am

Posted in code

Tagged with

Google collections

without comments

How often have your needed lookups based on keys as well as values in a Map? Some programmers (read <1%) worth their salt look at such an opportunity to write their own collection class. However most others end up cribbing about the collections library.

Well, rescue is at hand now.

Look up google-collections.

See BiMap? Exactly what you need!

If you ever needed multiple values attached to a single key; well, here’s MultiMap.

To the credit of the library designers; they are still upholding the java.util.collections tradition of providing classes with static methods that operate on or return the new collection types. See the class names ending in collection type plurals i.e. Multimaps, Multisets etc.

Written by shakhan

May 8, 2008 at 8:35 am

Posted in code

Tagged with

Hola amigo!

without comments

-module(hello).
-export([execute/0]).

execute() ->
    io:format("Hola amigo~n" ).

Written by shakhan

May 8, 2008 at 6:50 am

Posted in code

Tagged with