The Builder Design Pattern in Java

The builder design pattern in Java is one of the articles among the collection of articles dedicated to explaining OOP Design Patterns in Java.

In 1994, four authors, Addison-Wesley, by Erich Gamma, Richard Helm, Ralph Johnson, John Vissides wrote a book: Design Patterns: Elements of Reusable Object-Oriented Software. There they have included 23 object-oriented design patterns and Builder design pattern is one of them. The Builder design pattern is categorized as a Creational Pattern since it is used to create and configure objects.

Why Builder Design Pattern?

The Builder design pattern tries to solve two problems.

  • Creation of objects which has too many constructor arguments.
  • Developers may create incorrect state of objects because of the unawareness of the constructor arguments.

If a constructor has too many arguments, it takes lot of time for developers to create new object. Developer needs to check each and every arguments in the constructor and put that specific parameter value.

For example, imagine there two Double type attributes in the BankAccount constructor. One is for balance and the other is for the interest rate. If we put balance value for interest rate and interest rate value for balance, at the compile-time it won’t give us any errors. Maybe it won’t give us runtime errors. Because both are Double type variables, but the object that we have created in an incorrect state.

package com.prasadct.builderPattern;

public class BankAccount {
    private long accountId;
    private int branchId;
    private String accountType;
    private String ownerName;
    private double balance;
    private double interestRate;

    public BankAccount(){
        //No argument constructor
    }

    public BankAccount(long accountId, int branchId, String accountType, String ownerName, double balance, double interestRate) {
        this.accountId = accountId;
        this.branchId = branchId;
        this.accountType = accountType;
        this.ownerName = ownerName;
        this.balance = balance;
        this.interestRate = interestRate;
    }
}

Following is the way we create BankAccount object without Builder pattern.

BankAccount bankAccount = new BankAccount(887799,
                777,
                "Savings Account",
                "Prasad",
                22750.65,
                5.6);

Here we see only values but not what are they. So this is not readable or understandable. Also as I have mentioned earlier, we may have mixed the same type of arguments by accidentally and we won’t be aware of it until we me with inconsistent behavior at run time.

If we use a builder design pattern, our code will be readable, understandable and it reduces the risk of creating objects with incorrect states.

The Builder Design Pattern in Java

We have to remove the public constructor from the object and put builder within the object. So we don’t have a public constructor now to make mistakes. We have to use builder in order to create a new object.

package com.prasadct.builderPattern;

public class BankAccount {

    private long accountId;
    private int branchId;
    private String accountType;
    private String ownerName;
    private double balance;
    private double interestRate;

    private BankAccount() {
    }

    public static class Builder {
        private long accountId;
        private int branchId;
        private String accountType;
        private String ownerName;
        private double balance;
        private double interestRate;

        public Builder(){

        }

        public Builder withAccountId(long accountId) {
            this.accountId = accountId;
            return this;
        }

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

        public Builder setAccountType(String accountType) {
            this.accountType = accountType;
            return this;
        }

        public Builder withOwnerName(String ownerName) {
            this.ownerName = ownerName;
            return this;
        }

        public Builder currentBalance(double balance) {
            this.balance = balance;
            return this;
        }

        public Builder atInterestRate(double interestRate) {
            this.interestRate = interestRate;
            return this;
        }

        public BankAccount builder() {
            BankAccount bankAccount = new BankAccount();
            bankAccount.accountId = this.accountId;
            bankAccount.branchId = this.branchId;
            bankAccount.accountType = this.accountType;
            bankAccount.ownerName = this.ownerName;
            bankAccount.balance = this.balance;
            bankAccount.interestRate = this.interestRate;

            return bankAccount;
        }
    }
   
    //Getters and Setters committed here
}

Creating a new object is easy and it is more readable than earlier.

BankAccount bankAccount = new BankAccount.Builder()
                .withAccountId(8897799)
                .atBranchId(777)
                .setAccountType("Savings Account")
                .withOwnerName("Prasad")
                .currentBalance(22750.65)
                .atInterestRate(6.7)
                .builder();

Here we have more readable object creation code as it displays the argument that we are providing and we can have the more convenient naming for builder methods.

Also we don’t have to provide all the arguments. We can omit any of those. If we had constructors, we had to pass null for those values. But here we don’t need to to that kind of unnecessary steps when we need to create an object.

BankAccount bankAccount = new BankAccount.Builder()
                .withAccountId(8897799)
                .atBranchId(777)
                .builder();

Conclusion

Builder pattern removes the parameters of the constructor and provide us some readable methods to build objects. Also with builder pattern we don’t need to pass null values for parameters that we don’t have values. We just need to omit those builder methods. With builder pattern, we can have a object with correct state and the object creation code is more readable/understandable. Even though it nearly doubles the number of code lines in the object itself, the effort paid off in the long run as we have more clean, readable and understandable code.

15 thoughts on “The Builder Design Pattern in Java

  1. I like the helpful information you provide in your articles. I will bookmark your weblog and check again here frequently. I am quite sure I will learn lots of new stuff right here! Best of luck for the next! Shanon Mayne Donelle

  2. Hi there, I found your blog by way of Google whilst looking
    for a similar topic, your web site got here up, it looks good.

    I’ve bookmarked it in my google bookmarks.
    Hi there, simply become alert to your weblog via Google, and found that it is really informative.
    I am going to be careful for brussels. I’ll appreciate in case you proceed this
    in future. A lot of other people can be benefited from
    your writing. Cheers!

  3. Does your blog have a contact page? I’m having a tough time
    locating it but, I’d like to send you an e-mail. I’ve got some recommendations
    for your blog you might be interested in hearing. Either way, great site and I look forward to seeing it grow over time.

  4. It’s a shame you don’t have a donate button! I’d definitely donate to this outstanding blog!
    I guess for now i’ll settle for bookmarking and adding your RSS feed to my Google account.

    I look forward to fresh updates and will talk about this site with
    my Facebook group. Talk soon!

Leave a Reply

Your email address will not be published.