Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

Builder design pattern in Java

5.00/5 (5 votes)
30 Sep 2012CPOL3 min read 35.5K   184  
Explains the Builder design pattern in detail with example.

Introduction  

The Builder design pattern allows to create a complex object step by step and also enforces a process to create an object as a finished product. The construction of the object should be such that the same construction process can create different representations. Director controls the construction of the object and only the director knows what type of object to create.

For example, you can consider printing of a book. Printing of a book involves various steps such as printing the table of contents, preface, introduction, chapters, and conclusion. Finally you will get a complete book object. With the help of the same process, you can print books with different properties. 

As described by Gof:

"Separate the construction of a complex object from its representation so that the same construction process can create different representations" 

UML diagram:

Elements:

  • Builder
    • Specifies an abstract interface for creating parts of a product object. It defines steps for the construction of the product object.
  • ConcreteBuilder 
    • Constructs and assembles parts of the product by implementing the builder interface.
    • Provides an interface for retrieving the product.
  • Director
    • Constructs an object using builder interface. 
  • Product
    • Represents the complex object under construction. ConcreteBuilder builds the product's internal representation and defines the process by which it is assembled.

When to use it:  

  • Object creation algorithms should be independent of the system. 
  • The construction process must allow different representations for the object that has been constructed.
  • New creation algorithm can be added without changing the core code.
  • When you require runtime control over creation process.

WorkFlow: 

  • The client creates the director object and configures it with the desired builder object.
  • Director notifies the builder whenever a part of the product should be built.
  • Builder handles requests from the director and adds parts to the product.
  • The clients retrieve the product from the builder. 

Example:

You can consider printing of a book. Printing of a book involves various steps such as printing the table of contents, preface, introduction, chapters, and conclusion. Finally you will get the complete book object. With the help of the above process, you can write books with different properties.  BookWriter will instruct bookBuilder to print a book in steps and return the final book object.

Comparing to the generic UML diagram of builder pattern:

  • BookBuilder (Builder)
  • TechnicalBookBuilder (ConcreteBuilder)
  • FictionalBookBuilder (ConcreteBuilder)
  • BookWriter (Director)
  • Book (Product)

Java codes for above classes:

The following class is our product class. An object of this class will be returned by the builder. In this class, we have five parts to the product.

Book.java (Product):

Java
package org.arpit.javapostsforlearning.designpatterns;
 
public class Book {
 
 String introduction;
 String tableOfContent;
 String preface;
 String chapters;
 String glossary;
  
 public void setIntroduction(String introduction) {
  this.introduction = introduction;
 }
 public void setTableOfContent(String tableOfContent) {
  this.tableOfContent = tableOfContent;
 }
 public void setPreface(String preface) {
  this.preface = preface;
 }
 public void setChapters(String chapters) {
  this.chapters = chapters;
 }
 public void setGlossary(String glossary) {
  this.glossary = glossary;
 }
}

The following interface is our builder interface. The builder interface provides steps or processes. Here we have five steps - buidTableOfContent, buildPreface, buildIntroduction, buildChapters, buildGlossary. It also has a method to return a book (product) object.

BookBuilder.java (Builder):

Java
package org.arpit.javapostsforlearning.designpatterns;
 
public interface BookBuilder {
 
        public void buildTableOfContent();
        public void buildPreface();
        public void buildIntroduction();
        public void buildChapters();
        public void buildGlossary();
        public Book getBook();
}

The following class is our first implementation of the builder interface. We are having multiple concrete builder classes to support the same construction process creating multiple representations.

TechnicalBookBuilder.java(ConcreteBuilder):

Java
package org.arpit.javapostsforlearning.designpatterns;
 
public class TechnicalBookBuilder implements BookBuilder{
 private Book book;
 
 public TechnicalBookBuilder()
 {
  book=new Book();
 }
 public void buildTableOfContent() {
  System.out.println("printing technical table of content");
  book.setTableOfContent("technical table of content");
 }
 
 public void buildPreface() {
  System.out.println("printing preface");
  book.setTableOfContent("preface");
 }
 public void buildIntroduction() {
  System.out.println("printing technical introduction");
  book.setTableOfContent("technical introduction");
 }
 
 public void buildChapters() {
  System.out.println("printing technical chapters");
  book.setChapters("technical chapters");
 }
 
 public void buildGlossary() {
  System.out.println("printing technical glossary");
  book.setGlossary("Technical glossary");
 }
 
 public Book getBook() {
  return book;
 }
}

The following class is our second implementation of the builder interface.

FictionalBookBuilder.java(ConcreteBuilder):

Java
package org.arpit.javapostsforlearning.designpatterns;
 
public class FictionalBookBuilder implements BookBuilder{
 private Book book;
 
 public FictionalBookBuilder()
 {
  book=new Book();
 }
 public void buildTableOfContent() {
  System.out.println("printing fictional table of content");
  book.setTableOfContent("fictional table of content");
 }
 
 public void buildPreface(){
  System.out.println("printing preface");
  book.setTableOfContent("preface");
 }
 public void buildIntroduction() {
  System.out.println("printing fictional introduction");
  book.setTableOfContent("fictional introduction");
 }
 
 public void buildChapters() {
  System.out.println("printing fictional chapters");
  book.setChapters("fictional chapters");
 }
 
 public void buildGlossary() {
  System.out.println("printing fictional glossary");
  book.setGlossary("Fictional glossary");
 }
 
 public Book getBook() {
  return book;
 }
 
}

The following class is our director class which will instruct BookBuilder to print parts of the book and return the final book object.

BookWriter.java(Director):

Java
package org.arpit.javapostsforlearning.designpatterns;
public class BookWriter {
 
 BookBuilder bookBuilder;
 
 public BookWriter(BookBuilder bookBuilder) {
  super();
  this.bookBuilder = bookBuilder;
 }
 
 public Book getBook()
 {
  return this.bookBuilder.getBook();
 }
 
 public void printBook()
 {
  this.bookBuilder.buildTableOfContent();
  this.bookBuilder.buildPreface();
  this.bookBuilder.buildIntroduction();
  this.bookBuilder.buildChapters();
  this.bookBuilder.buildGlossary();
 }
}
BuilderDesignPatternMain.java:
package org.arpit.javapostsforlearning.designpatterns;
 
public class BuilderDesignPatternMain {
 
 
 public static void main(String[] args) {
  
  System.out.println("Printing technical book:");
  BookBuilder technialbookBuilder=new TechnicalBookBuilder();
  BookWriter technicalBookWriter=new BookWriter(technialbookBuilder);
  technicalBookWriter.printBook();
  Book technicalbook=technicalBookWriter.getBook();
  System.out.println("Technical Book Printed:"+technicalbook);
  System.out.println("******************************************");
  System.out.println("Printing fictional book:");
  BookBuilder fictionalbookBuilder=new FictionalBookBuilder();
  BookWriter fictionalBookWriter=new BookWriter(fictionalbookBuilder);
  fictionalBookWriter.printBook();
  Book fictionalbook=fictionalBookWriter.getBook();
  System.out.println("Fictionalbook book printed:"+fictionalbook);
 }
}

For printing technical book, we have configured bookWriter object with technicalBookBuilder. BookWriter instructed to technicalbookbuilder to print book and return final book object. Same is true for a fictional book. So with help of the same construction process, we have printed two kinds of books, .i.e., technical and fictional.

Output:

Printing technical book:
printing technical table of content
printing preface
printing technical introduction
printing technical chapters
printing technical glossary
Technical Book printed:org.arpit.javapostsforlearning.designpatterns.Book@1888759
******************************************
Printing fictional book:
printing fictional table of content
printing preface
printing fictional introduction
printing fictional chapters
printing fictional glossary
Fictionalbook book printed:org.arpit.javapostsforlearning.designpatterns.Book@1f1fba0

References:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)