Design Patterns: The Builder Pattern

2017 December 4 @ 10:21pm by erik


In this blog post, Riaan Nel goes over an example of the Builder Pattern, a creational pattern used to create and configure objects. The following example is from Effective Java by Joshua Bloch.

The Problem

In this example, we are part of a Java team working on software for a bank. We need a way to represent banks accounts.

BankAccount.java

public class BankAccount {
    private long accountNumber;
    private String owner;
    private String branch;
    private double balance;
    private double interestRate;

    public BankAccount(long accountNumber, 
                       String owner,
                       String branch,
                       double balance,
                       double interestRate) 
       {
        this.accountNumber = accountNumber;
        this.owner = owner;
        this.branch = branch;
        this.balance = balance;
        this.interestRate = interestRate;
   }
    //Getters and setters omitted for brevity.
}

We run into two problems in the about code:

  • Too many constructor arguments
  • Incorrect object state

The Pattern

The builder pattern “allows us to write readable, understandable code to set up complex objects. It is often implemented with a fluent interface, which you may have seen in tools like Apache Camel or Hamcrest.” The builder will


public class BankAccount {
    public static class Builder {
        private long accountNumber; 
        private String owner;
        private String branch;
        private double balance;
        private double interestRate;

        public Builder(long accountNumber) {
            this.accountNumber = accountNumber;
        }

        public Builder withOwner(String owner){
            this.owner = owner;
            return this; 
        }

        public Builder atBranch(String branch){
            this.branch = branch;
            return this;
        }

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

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

        public BankAccount build(){
            BankAccount account = new BankAccount(); 
            account.accountNumber = this.accountNumber;
            account.owner = this.owner;
            account.branch = this.branch;
            account.balance = this.balance;
            account.interestRate = this.interestRate;
            return account;
        }
    }
    //Fields omitted for brevity.
    private BankAccount() {
        //Constructor is now private.
    }
    //Getters and setters omitted for brevity.
}

We can create new account with the following code:


BankAccount account = new BankAccount.Builder(1234L)
            .withOwner("Marge")
            .atBranch("Springfield")
            .openingBalance(100)
            .atRate(2.5)
            .build();
BankAccount anotherAccount = new BankAccount.Builder(4567L)
            .withOwner("Homer")
            .atBranch("Springfield")
            .openingBalance(100)
            .atRate(2.5)
            .build();

This makes code clearer and more verbose. Using the Builder pattern is a good solution if you find yourself having to add more and more parameters to the constructor resulting in error-prone and hard to read code. I chose this resource because I wanted to learn more about design patterns, and I did not know much about this pattern. I learned how the Builder pattern can help simplify code that may get too complex and hard to read. The content of the post is good quality and the example used was simple and easy to understand, making learning how the Builder pattern works easier. I plan to use this information when in my professional career whenever the Builder pattern would be the best solution.

0 comments

Leave a Reply

 

by erik christensen - powered by wordpress