Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is a nested Builder class really necessary as described in Effective Java?

So, in the famous Effective Java book, it introduces a Builder pattern where you can have an inner static Builder class to instantiate a class. The book suggests the following design of a class:

public class Example {
    private int a;
    private int b;

    public static class Builder() {
        private int a;
        private int b;

        public Builder a(int a) {
            this.a = a;
            return this;
        }

        public Builder b(int b) {
            this.b = b;
            return this;
        }

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

    private Example(Builder builder) {
        this.a = builder.a;
        this.b = builder.b;
    }
}

However I have failed to understand why do we really need an inner Builder class? The above code have duplicate lines for field declarations (int a, b), this would become relatively messy if we had more fields.

Why not just get rid of the Builder class, and let Example class take on all the set methods that were in Builder class?

So to instantiate Example, it would become Example e = new Example().a(3).b.(3); instead of Example e = new Example.Builder.a(3).b(3).build();


NOTE: The book suggests this pattern for classes that have a long list of parameters to be set.

like image 275
Joel Min Avatar asked Apr 05 '16 05:04

Joel Min


1 Answers

Builder is a pattern for the construction of complex objects. I wouldn't count your example as complex; indeed, the builder adds an awful lot of unnecessary code, rather than just using constructor parameters.

There are a few reasons why you'd want to use a builder:

  • To construct complex immutable objects. Immutable objects need to have final (or logically final) fields, so they must be set at construction time.

    Let's say that you have N fields, but you only want to explicitly set some of them in certain use cases. You would need up to 2^N constructors to cover all of the cases - known as "telescoping", since the length of the parameter list gets longer and longer. The builder allows you to model optional parameters: if you don't want to set that parameter, don't call that setter method.

  • To allow self-documentation of the parameters' meaning. By naming the setter methods appropriately, you can see what the values mean at a glance.

    It also helps to verify that you are not accidentally reversing parameters of the same type, since you can see what each value is used for.

like image 114
Andy Turner Avatar answered Nov 15 '22 02:11

Andy Turner