Builder Pattern

Imagine you write an entity for your Java Application. Your entity has a bunch of attributes.

package com.javadevcorner.entity;


import java.util.List;

/**
 * @author javadevcorner.com
 */
public class Customer {
    
    private int id;
    private String name;
    private String customerNumber;
    private List relatedProducts; 
    private String phonenumber; 
    private String fax; 
    private String email;

    public Customer() {
    }

    public Customer(int id, 
                    String name, 
                    String customerNumber, 
                    List relatedProducts, 
                    String phonenumber, 
                    String fax, 
                    String email) {
        this.id = id;
        this.name = name;
        this.customerNumber = customerNumber;
        this.relatedProducts = relatedProducts;
        this.phonenumber = phonenumber;
        this.fax = fax;
        this.email = email;
    }


   //setter and getter and overriden methods...
}

As you see, in this Customer Entity we have the default constructor and the fully qualified constructor.

Now, later in the development of your Application you recognize that you have to add another attribute for your entity. How you manage that?
Refactor your constructor(s) and update all your code?
Write a new constructor just for this purpose?

These are not good practise. Further more your entity will become confusing.
So now this is the time for the glorious Builder Pattern.

Implementing the Builder Pattern

There are different ways to implement the Builder Pattern in your code.
I will show you the one approach I mostly use for myself.

package com.javadevcorner.entity;

import java.util.List;

/**
 * @author javadevcorner.com
 */
public class Customer {

    private final int id;
    private final String name;
    private final String customerNumber;
    private final List relatedProducts;
    private final String phonenumber;
    private final String fax;
    private final String email;

    private Customer(CustomerBuilder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.customerNumber = builder.customerNumber;
        this.relatedProducts = builder.relatedProducts;
        this.phonenumber = builder.phonenumber;
        this.fax = builder.fax;
        this.email = builder.email;
    }

    
    //setter and getter and overriden methods...
    
    public static class CustomerBuilder {

        private int id;
        private String name;
        private String customerNumber;
        private List relatedProducts;
        private String phonenumber;
        private String fax;
        private String email;

        public CustomerBuilder Id(int id) {
            this.id = id;
            return this;
        }

        public CustomerBuilder Name(String name) {
            this.name = name;
            return this;
        }

        public CustomerBuilder CustomerNumber(String customerNumber) {
            this.customerNumber = customerNumber;
            return this;
        }

        public CustomerBuilder RelatedProducts(List products) {
            this.relatedProducts = products;
            return this;
        }

        public CustomerBuilder PhoneNumber(String phoneNumber) {
            this.phonenumber = phoneNumber;
            return this;
        }

        public CustomerBuilder Fax(String fax) {
            this.fax = fax;
            return this;
        }

        public CustomerBuilder Email(String email) {
            this.email = email;
            return this;
        }

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

    }
}

Important things you have to notice:

  • Customer Constructor become private
  • The CustomerBuilder methods for setting the attribute values always return the Builder Type via this.
  • Final method is build() which returns a new Customer
  • The Builder Pattern is used in Fluent Way (see following code)

Using the Builder Pattern in your Code

Now, after we have implemented the Builder Pattern, let´s replace the well-known instantiation via the constructors with our Builder:

Customer customer = new Customer.CustomerBuilder()
                        .CustomerNumber("123456789")
                        .Email("customer1@CustomerCompany.de")
                        .Fax("")
                        .Id(1)
                        .Name("Bruce Wayne")
                        .PhoneNumber("41941614946")
                        .RelatedProducts(Arrays.asList(new Product(1)))
                        .build();

System.out.println(customer.toString());

Notice the Fluent Way and the .build() Method at the end of the expression.

One big deal of this Pattern is also that you can omit some attributes if you don´t know them yet or just don´t need them. Try it out. Just build a customer without a phonenumber and without related Products.

So thanks for reading and have fun using the Builder Pattern.

 

Feel free to share