How to improve the builder pattern?
        Posted  
        
            by tangens
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by tangens
        
        
        
        Published on 2009-10-28T17:14:22Z
        Indexed on 
            2010/03/25
            6:53 UTC
        
        
        Read the original article
        Hit count: 632
        
Motivation
Recently I searched for a way to initialize a complex object without passing a lot of parameter to the constructor. I tried it with the builder pattern, but I don't like the fact, that I'm not able to check at compile time if I really set all needed values.
Traditional builder pattern
When I use the builder pattern to create my Complex object, the creation is more "typesafe", because it's easier to see what an argument is used for:
new ComplexBuilder()
        .setFirst( "first" )
        .setSecond( "second" )
        .setThird( "third" )
        ...
        .build();
But now I have the problem, that I can easily miss an important parameter. I can check for it inside the build() method, but that is only at runtime. At compile time there is nothing that warns me, if I missed something.
Enhanced builder pattern
Now my idea was to create a builder, that "reminds" me if I missed a needed parameter. My first try looks like this:
public class Complex {
    private String m_first;
    private String m_second;
    private String m_third;
    private Complex() {}
    public static class ComplexBuilder {
        private Complex m_complex;
        public ComplexBuilder() {
            m_complex = new Complex();
        }
        public Builder2 setFirst( String first ) {
            m_complex.m_first = first;
            return new Builder2();
        }
        public class Builder2 {
            private Builder2() {}
            Builder3 setSecond( String second ) {
                m_complex.m_second = second;
                return new Builder3();
            }
        }
        public class Builder3 {
            private Builder3() {}
            Builder4 setThird( String third ) {
                m_complex.m_third = third;
                return new Builder4();
            }
        }
        public class Builder4 {
            private Builder4() {}
            Complex build() {
                return m_complex;
            }
        }
    }
}
As you can see, each setter of the builder class returns a different internal builder class. Each internal builder class provides exactly one setter method and the last one provides only a build() method.
Now the construction of an object again looks like this:
new ComplexBuilder()
    .setFirst( "first" )
    .setSecond( "second" )
    .setThird( "third" )
    .build();
...but there is no way to forget a needed parameter. The compiler wouldn't accept it.
Optional parameters
If I had optional parameters, I would use the last internal builder class Builder4 to set them like a "traditional" builder does, returning itself.
Questions
- Is this a well known pattern? Does it have a special name?
- Do you see any pitfalls?
- Do you have any ideas to improve the implementation - in the sense of fewer lines of code?
© Stack Overflow or respective owner