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.
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
also read:
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)
ConcreteBuilder (CarLoanBuilder, HomeLoanBuilder, PersonalLoanBuilder)
Director (LoanManager)
Product (Loan)
Let’s see the common problems where you should apply the Builder Pattern.
The following pros of using the Builder pattern:
The following cons of using the Builder pattern:
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.
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.
LoanBuilder.java
package com.doj.patterns.creational.builder; public interface LoanBuilder { void loanApply(); void loanApproval(); void loanSanction(); Loan loanDisburse(); }
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; } }
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(); } }
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); } }
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]
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…