Monday, January 14, 2013

Giving up on Java's Constructors

As much as I'm not always a fan of objective-c, I really like the method calling syntax:

    Merger merger = [[Merger alloc] initWithFirstString:"foo" andSecondString:"Bar" startingAt:1 suffleOutput:false lowercaseOutput:true];
If you wanted to write that in java, it would be fairly incomprehensible:

    Merger merger = new Merger("foo", "Bar", 1, false, true);

Just looking at this, who the hell knows what "foo" and "bar" are and why there is a number and a couple bools after it. You've have to look at the docs. Assuming you wrote docs... You could just nuke all the constructor params and create a whole lot of setters, and do this:

    Merger merger = new Merger();
    merger.setFirstString("foo");
    ...

But that sort of stinks too. First, it six lines of code for something that should go in one. Second, what if you want those parameters to be final?

So I've basically given up on constructors in java and added the following eclipse template to my tool belt:

            ${:import(com.google.common.base.Preconditions)}
            public static ${enclosing_type}Builder Builder() {
                return new ${enclosing_type}Builder();
            }

            public static class ${enclosing_type}Builder {
            private String property = null;

            @SuppressWarnings("synthetic-access")
            public ${enclosing_type} build() {
                Preconditions.checkState(this.property != null,
                    "property is required.");
                return new ${enclosing_type}(this.property);
            }

            public ${enclosing_type}Builder property(
                final String property) {
                this.property = property;
                return this;
            }
        }

It ends up being quite a bit longer than the original java code, but only slightly longer than objective-c. And I'm fairly certain that the next person that comes across my code is going to be very clear about what I was trying to do here.

If Eclipse templates had the support, I'd have it find all the members of constructors in the enclosing type for the builder and run checkState on all the final members but I'm fairly certain that would require plugin development.

What do you think?

1 comment:

Unknown said...

You have very interesting way of thinking, I havent seen such solution of this problem before. But as for me its a little bit hard for understanding, so I found out another solution on this site and explanation what is a constructor in java https://explainjava.com/java-constructor/ hope it will be useful for you as well.