Skip to content

Builder

Dmitriy Kotov edited this page Feb 7, 2017 · 1 revision

Overall information

Creational pattern.

Provides a way to build objects in multiple steps, thus isolating the code, which is responsible for creating an object from the code, which represents object itself.


Advantages:

+ Might be quite useful if we want to build an immutable object, which might have a lot of optional parameters. Instead of creating numerous constructors for each scenario, in which one of the optional attributes is absent, we introduce the Builder pattern in the following way:

Here's our builder:


    public static class Builder {

        private final String firstMandatoryAttribute;
        private final String secondMandatoryAttribute;

        private Integer firstOptionalAttribute;
        private String  secondOptionalAttribute;
        private Integer thirdOptionalAttribute;


        private Builder(String firstMandatoryAttribute, String secondMandatoryAttribute) {
            this.firstMandatoryAttribute = firstMandatoryAttribute;
            this.secondMandatoryAttribute = secondMandatoryAttribute;
        }

        public Builder withFirstOptionalAttribute(int firstOptionalAttribute) {
            this.firstOptionalAttribute = firstOptionalAttribute;

            return this;
        }

        public Builder withSecondOptionalAttribute(String secondOptionalAttribute) {
            this.secondOptionalAttribute = secondOptionalAttribute;

            return this;
        }

        public Builder withThirdOptionalAttribute(int thirdOptionalAttribute) {
            this.thirdOptionalAttribute = thirdOptionalAttribute;

            return this;
        }

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

MyObject is then constructed in the following way (assume that Builder is static inner class, located inside of MyObject class:

 public static class MyObject {

        private final String firstMandatoryAttribute;
        private final String secondMandatoryAttribute;

        private final Integer firstOptionalAttribute;
        private final String  secondOptionalAttribute;
        private final Integer thirdOptionalAttribute;

        public MyObject(Builder builder) {
            this.firstMandatoryAttribute =  builder.firstMandatoryAttribute;
            this.secondMandatoryAttribute = builder.secondMandatoryAttribute;
            this.firstOptionalAttribute =   builder.firstOptionalAttribute;
            this.secondOptionalAttribute =  builder.secondOptionalAttribute;
            this.thirdOptionalAttribute =   builder.thirdOptionalAttribute;
        }

        //getters,equals,hashcode and so on
  }

As you can see, there is no need to produce multiple constructors anymore, the whole construction part is now encapsulated inside of a Builder object, and MyObject's purpose now is only to represent state.


Project example:

At this project we have the following model:

We have a Person class, which has the following fields:

- firstName : String - mandatory parameter

- lastName : String - mandatory parameter

- age : Integer - optional parameter

- education: Education - optional parameter

- maritalStatus : MaritalStatus - optional parameter

To simplify Person's code, we encapsulate construction logic into PersonBuilder class.

PersonBuilder itself looks very much alike with the example above (Builder) class, and here is how we use it:

Person person = builder("John", "Doe")
                .withAge(47)
                .withEducation(MASTERS)
                .withMaritalStatus(MARRIED)
                .build();
Clone this wiki locally