Design Pattern

Builder Design Pattern – Creational Patterns

Builder Design Pattern comes under the creational design pattern, it is used to construct complex object step by step and finally, it will return the complete object. The logic and process of object creation should be generic so that you can use it to create a different concrete implementation of the same object type.

Builder Design Pattern

This pattern simplifies the construction of the complex objects and it hides the details of the object’s construction from the client caller code. When you using this pattern, remember you have to build one step at a time means you have to break object construction login into multiple phases unlike other patterns such as abstract factory, factory method pattern build the object in a single step.

“Separate the construction of a complex object from its representation so that the same construction process can create different representations” –According to GoF Patterns

Spring 5 Design Pattern Book

You could purchase my Spring 5 book that is with title name “Spring 5 Design Patterns“. This book is available on the Amazon and Packt publisher website. Learn various design patterns and best practices in Spring 5 and use them to solve common design problems. You could use an author discount to purchase this book by using code- “AUTHDIS40“.

UML class diagram for the Builder Pattern

Let’s see the following class diagram for the Builder Pattern. It illustrates the component classes and interfaces for this pattern.

Let’s see these classes and objects participating in this pattern are:

Builder (LoanBuilder)

  • This is an abstract class or interface and it specifies an abstract interface for creating parts of a Product object

ConcreteBuilder (CarLoanBuilder, HomeLoanBuilder, PersonalLoanBuilder)

  • These are concrete classes and constructs and assembles parts of the product by implementing the Builder interface
  • ConcreteBuilder defines and keeps track of the representation it creates
  • It provides an interface for retrieving the product

Director (LoanManager)

  • It constructs an object using the Builder interface

Product (Loan)

  • It represents the complex object under construction. ConcreteBuilder builds the product’s internal representation and defines the process by which it’s assembled
  • It includes classes that define the constituent parts, including interfaces for assembling the parts into the final result

Applicability

Let’s see the common problems where you should apply the Builder Pattern.

  • In the enterprise application, you can apply Builder Pattern where object creation has done by using multiple steps. In each step you do some unit of process, in this process, you set some required parameters and some optional parameters and after the final step, you will get a complex object.
  • The “Builder” pattern is an object creation software design pattern. The intention is to abstract the steps of construction so that different implementations of these steps can construct different representations of objects. Often, the builder pattern is used to build products in accordance with the composite pattern.

Pros of the Builder Pattern

The following pros of using the Builder pattern:

  • It provides you with complete isolation between the construction and representation of an object.
  • The Builder pattern allows you to construct the object in the multiple phases, so you have greater control over the construction process.
  • This pattern provides flexibility to vary an object’s internal representation.

Cons of the Builder Pattern

The following cons of using the Builder pattern:

  • The builder pattern is verbose and requires code duplication as Builder needs to copy all fields from Original or Item class.

Examples of Builder Pattern Implementation

In the Spring Framework, you can see the implementation of the builder design pattern transparently in some functionalities. As below classes are based on the Builder Design Pattern in the Spring Framework.

  • EmbeddedDatabaseBuilder
  • AuthenticationManagerBuilder
  • UriComponentsBuilder
  • BeanDefinitionBuilder
  • MockMvcWebClientBuilder

Sample Implementation of Builder Design Pattern

Let’s discuss a business case related the banking as I discussed throughout this book, here I am taking one business case related to Loan product of any bank, I am using Builder Design Pattern to solve the problems of banking loan example. So main problem in this example is that the customer of the bank who wants a loan, to perform the steps to get a loan either Home Loan or Car Loan and that process has multiple steps, so to maintain correct order by customer is difficult. So, how will we address this in real life? We will contact a loan manager who knows the process to construct a loan.

The second problem was that we require different types of loans, such as home loan, car loan, and personal loan. So next, we will contact to loan manager of the bank who specializes in building specific types of loans. A loan manager knows how to put things together with actual documentation and verification processes for a loan. For example, a home loan manager knows all about documentation and verification for home loan application. Similarly, a car loan manager knows all about documentation and verification for car loan application. So from now on, whenever we need a loan, the loan manager will direct a builder to build the loan.

In our application, we can model the loan manager by creating a LoanManager class. Then we can model the builders by first creating a LoanBuilder interface and then builder classes, such as HomeLoanBuilder and CarLoanBuilder that implement the LoanBuilder interface. Here, notice that we have added a layer of abstraction by providing an interface. This is because we do not want our loan manager to be tied with a particular loan builder. The loan manager should be able to direct any builder that implements the LoanBuilder interface to build a loan. This will also allow us to later add new builders without making changes to the existing application code.

Step 1: Create an interface Item representing loan item.

LoanBuilder.java

package com.doj.patterns.creational.builder;

public interface LoanBuilder {
	void loanApply();
	void loanApproval();
	void loanSanction();
	Loan loanDisburse();
}

Step 2: Let’s create concrete classes implementing the LoanBuilder interface

CarLoanBuilder.java

package com.doj.patterns.creational.builder;

/**
 * @author Dinesh.Rajput
 *
 */
public class CarLoanBuilder implements LoanBuilder {
	private Loan loan;
	
	public CarLoanBuilder() {
		super();
		this.loan = new Loan();
	}

	@Override
	public void loanApply() {
		loan.setLoanAmount(Double.valueOf(500000));
		loan.setLoanName("Car Loan");
		System.out.println("CarLoanBuilder: Applied for Car Loan for Amount 500000");
	}

	@Override
	public void loanApproval() {
		loan.setApproved(true);
		System.out.println("CarLoanBuilder: Car Loan has been Approved...");
	}

	@Override
	public void loanSanction() {
		loan.setLoanAccount(30000l);
		loan.setLoanFee(Double.valueOf(5000));
		loan.setRoi(Double.valueOf(10.3));
		System.out.println("CarLoanBuilder: Car Loan has been processed and sanctioned...");
		System.out.println("Details: Total processing fee 5000 and interest rate 10.3 and loan account 30000...");
	}

	@Override
	public Loan loanDisburse() {
		return this.loan;
	}

}

PersonalLoanBuilder.java

package com.doj.patterns.creational.builder;

/**
 * @author Dinesh.Rajput
 *
 */
public class PersonalLoanBuilder implements LoanBuilder {
	private Loan loan;
	
	public PersonalLoanBuilder() {
		super();
		this.loan = new Loan();
	}

	@Override
	public void loanApply() {
		loan.setLoanAmount(Double.valueOf(200000));
		loan.setLoanName("Personal Loan");
		System.out.println("PersonalLoanBuilder: Applied for Personal Loan for Amount 200000");
	}

	@Override
	public void loanApproval() {
		loan.setApproved(true);
		System.out.println("PersonalLoanBuilder: Personal Loan has been Approved...");
	}

	@Override
	public void loanSanction() {
		loan.setLoanAccount(20000l);
		loan.setLoanFee(Double.valueOf(2000));
		loan.setRoi(Double.valueOf(14.3));
		System.out.println("PersonalLoanBuilder: Personal Loan has been processed and sanctioned...");
		System.out.println("Details: Total processing fee 2000 and interest rate 14.3 and loan account 20000...");
	}

	@Override
	public Loan loanDisburse() {
		return this.loan;
	}

}

HomeLoanBuilder.java

package com.doj.patterns.creational.builder;

/**
 * @author Dinesh.Rajput
 *
 */
public class HomeLoanBuilder implements LoanBuilder {
	
	private Loan loan;
	
	public HomeLoanBuilder() {
		super();
		this.loan = new Loan();
	}

	@Override
	public void loanApply() {
		loan.setLoanAmount(Double.valueOf(4000000));
		loan.setLoanName("Home Loan");
		System.out.println("HomeLoanBuilder: Applied for Home Loan for Amount 4000000");
	}

	@Override
	public void loanApproval() {
		loan.setApproved(true);
		System.out.println("HomeLoanBuilder: Home Loan has been Approved...");
	}

	@Override
	public void loanSanction() {
		loan.setLoanAccount(10000l);
		loan.setLoanFee(Double.valueOf(40000));
		loan.setRoi(Double.valueOf(8.30));
		System.out.println("HomeLoanBuilder: Home Loan has been processed and sanctioned...");
		System.out.println("Details: Total processing fee 40000 and interest rate 8.3 and loan account 1000...");
	}

	@Override
	public Loan loanDisburse() {
		return this.loan;
	}
	
}

Step 3: Let’s create LoanManager class to build the LoanBuilder.

LoanManager.java

package com.doj.patterns.creational.builder;

/**
 * @author Dinesh.Rajput
 *
 */
public class LoanManager {
	private LoanBuilder loanBuilder;

	public LoanManager(LoanBuilder loanBuilder) {
		super();
		this.loanBuilder = loanBuilder;
	}
	
	public Loan buildLoan(){
		this.loanBuilder.loanApply();
		this.loanBuilder.loanApproval();
		this.loanBuilder.loanSanction();
		return this.loanBuilder.loanDisburse();
	}
}

Step 4: BuilderPatternMain uses LoanManager to demonstrate builder pattern.

BuilderPatternMain.java

package com.doj.patterns.creational.builder;

/**
 * @author Dinesh.Rajput
 *
 */
public class BuilderPatternMain {

	public static void main(String[] args) {
		LoanManager loanManager = new LoanManager(new HomeLoanBuilder());
		Loan homeLoan = loanManager.buildLoan();
		System.out.println(homeLoan);
		System.out.println("--------------------------------------------------\n");
		
		loanManager = new LoanManager(new CarLoanBuilder());
		Loan carLoan = loanManager.buildLoan();
		System.out.println(carLoan);
		System.out.println("--------------------------------------------------\n");
		
		loanManager = new LoanManager(new PersonalLoanBuilder());
		Loan personalLoan = loanManager.buildLoan();
		System.out.println(personalLoan);
	}

}

Step 5: Let’s run the above demo class and verify the output.

HomeLoanBuilder: Applied for Home Loan for Amount 4000000
HomeLoanBuilder: Home Loan has been Approved...
HomeLoanBuilder: Home Loan has been processed and sanctioned...
Details: Total processing fee 40000 and interest rate 8.3 and loan account 1000...
Loan [roi=8.3, loanAmount=4000000.0, loanName=Home Loan, loanAccount=10000, loanFee=40000.0, approved=true]
--------------------------------------------------

CarLoanBuilder: Applied for Car Loan for Amount 500000
CarLoanBuilder: Car Loan has been Approved...
CarLoanBuilder: Car Loan has been processed and sanctioned...
Details: Total processing fee 5000 and interest rate 10.3 and loan account 30000...
Loan [roi=10.3, loanAmount=500000.0, loanName=Car Loan, loanAccount=30000, loanFee=5000.0, approved=true]
--------------------------------------------------

PersonalLoanBuilder: Applied for Personal Loan for Amount 200000
PersonalLoanBuilder: Personal Loan has been Approved...
PersonalLoanBuilder: Personal Loan has been processed and sanctioned...
Details: Total processing fee 2000 and interest rate 14.3 and loan account 20000...
Loan [roi=14.3, loanAmount=200000.0, loanName=Personal Loan, loanAccount=20000, loanFee=2000.0, approved=true]

Previous
Next
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

2 years ago