Builders Revisited

You are probably informed that JavaFX builders are deprecated within Java 8 and will be removed from jfxrt.jar into Java 9.

The first time I saw ‘Builders’, I thought => “Oh, yet another dot-parenthesis bullshit !”. At this time I was reviewing JavaFX 2 beta API to replace our Flex stack, because we really needed multi-threading capabilities for managing complex and big data. (flex was still supported by Adobe…, and yes I’m a RIA fan :). It’s so easy to write cryptic and  obfuscated code in ActionScript 3 + MXML.

But I gave them a try and thanks to amazing Eclipse formatter, I have found them nice and really convenient (less verbose and allowing imbrication).

When I read Michael‘s blog post about them [link here], I thought: “Yeah!!!  these builders really rock !!”.

Only stupid developers never change their minds , no ?? :p

Deprecated, argggg

Then , I read the famous discussion about the builder removal due to [EDIT]size restriction to reach the mobility goal; but especially to a fixed bug that allows Builder working on Java  6 & 7 but not 8 in certain cases explained into the discussion (Sorry to have implied that the mobility goal was the main reason)[/EDIT]. And I though that I should be primarly focused on Java 7 and JRebirth development instead of future JavaFX internal roadmap.

But this idea hasn’t been abandoned and JavaFX builders are now marked as deprecated into Java 8. As many of us, I saw a lot of deprecated warnings into my so nicely crafted code…. Ughhh.

So what can we do to workaround this limitation:

  • Nothing
  • Hack
  • Break

Doing nothing !

We can wait and ignore these warnings; later we will use the new jar that will be provided by Oracle. It will add some extra bytes into our applications. Until then, all mobile devices will have enough memory to manage them smoothly …
It could be risky if things don’t evolve.

Hacking Bytes

What about manipulating some byte-code ? it could be possible to write a plugin that parse all .class files to remove all Builders usage and replace them with standard declarations (with getters and setters).

In example it could be performed using ASM.

perhaps it could become quite hard to manage some imbricated code like this one, so can we find a more simple  way ?

    public void start() {
        SequentialTransitionBuilder.create()
                .children(

                        buildBeanAnimation(this.ratioLabel, this.ratioCircle, MTColors.RESULT_RATIO.get()),
                        buildBeanAnimation(this.timeLabel, this.timeBean, MTColors.RESULT_TIME.get()),

                        ParallelTransitionBuilder.create().children(
                                TranslateTransitionBuilder.create().node(this.monsterImage).delay(Duration.millis(500)).duration(Duration.millis(400)).byY(-766).build(),
                                buildBeanAnimation(this.successLabel, this.successBean, MTColors.RESULT_SUCCESS.get()),
                                FadeTransitionBuilder.create().node(this.successIcon).duration(Duration.millis(500)).fromValue(0).toValue(1).build()
                                )
                                .build(),

                        ParallelTransitionBuilder.create().children(
                                buildBeanAnimation(this.failureLabel, this.failureBean, MTColors.RESULT_FAILURE.get()),
                                FadeTransitionBuilder.create().node(this.failureIcon).duration(Duration.millis(500)).fromValue(0).toValue(1).build()
                                )
                                .build()

                )

                .build().playFromStart();

    }

Breaking Conventions

JavaFX builders are great because they hide Java Bean dirt chars to focus on business code.
One thing that is really boring with Java Beans is the famous Getters and Setters, writing them is tedious. Obviously code generator will do the dirt job but when managing your object you must deal with them. At the opposite a builder is really developer-friendly and allow concise code !

So could we create an Hybrid JavaBean auto-buildable ?

Version with an old builder:

this.multiplicationTable.add(ExpressionBuilder.create()
	                .left(leftOperand)
	                .operator(Operator.multiplication)
	                .right(rightOperand)
	                .result(leftOperand * rightOperand)
	                .build()
	                );

New version with a SmartJavaBean:

this.multiplicationTable.add(Expression.create()
                        .left(leftOperand)
                        .operator(Operator.multiplication.toString())
                        .right(rightOperand)
                        .result(leftOperand * rightOperand)
                        );

Getters and setters guarantee encapsulation for private fields, but nothing forbid us to name them like we want !

With the newer way we have only one class with only some additional chars, and we have same behaviors than with older builders.

Let’s compare a single field declaration:

Before:

    private final SimpleIntegerProperty leftProperty = new SimpleIntegerProperty();

    public int getLeft() {
        return this.leftProperty.get();
    }

    public void setLeft(final int left) {
        this.leftProperty.set(left);
    }

    public SimpleIntegerProperty leftProperty() {
        return this.leftProperty;
    }

After:

    private final SimpleIntegerProperty leftProperty = new SimpleIntegerProperty();

    public int left() {
        return this.leftProperty.get();
    }

    public Expression left(final int left) {
        this.leftProperty.set(left);
        return this;
    }

    public SimpleIntegerProperty leftProperty() {
        return this.leftProperty;
    }

the code difference is negligible, even more if we use a Smart Java Bean code generator (WIP) and it looks like implicit getters & setters (AS3 & C#).

Another small addition is required to start the chain, I use the same method name of JavaFX builders.
Note that the bean constructor could be private to force the usage of the integrated builder.

    public static Expression create() {
        return new Expression();
    }

You can browse original files on Github if you want to compare them:

ExpressionBuilder (old version)
Expression (old version)
ExpressionBuilderService (old version)

Expression (Smart Java Bean version)
ExpressionBuilderService (using Smart Java Bean)

Is it time to break some conventions ? or is it a dumb idea, let us know your opinion !

One thought on “Builders Revisited

Leave a Reply