Seth Barrett

Daily Blog Post: March 22nd, 2023

design1

Mar 22nd, 2023

Understanding the Builder Pattern in Java

Welcome back to our series on design patterns for Object-Oriented Programming (OOP) in Java. In this post, we'll be exploring the Builder Pattern, which is a creational design pattern that separates the construction of a complex object from its representation, allowing us to create different representations using the same construction process.

The Builder Pattern is used when we need to create a complex object that involves multiple steps. Instead of creating the object directly and specifying all its details at once, we use a builder object to construct the object step by step. This allows us to create different representations of the object using the same building process.

Let's take a look at the different components of the Builder Pattern:

  1. Product:

    The Product is the complex object that we want to create using the Builder Pattern.

  2. Builder:

    The Builder is an interface that defines the methods for creating the different parts of the product. This interface is implemented by the concrete builders.

  3. Concrete Builder:

    The Concrete Builder is a class that implements the Builder interface, and provides methods for creating the different parts of the product. The concrete builder is responsible for constructing the product step by step.

  4. Director:

    The Director is a class that controls the building process using a builder object. The director is responsible for coordinating the construction of the product.

Now, let's see an example of how we can implement the Builder Pattern in Java:

public class Product {
    private String part1;
    private String part2;
    private String part3;
 
    public void setPart1(String part1) {
       this.part1 = part1;
    }
 
    public void setPart2(String part2) {
       this.part2 = part2;
    }
 
    public void setPart3(String part3) {
       this.part3 = part3;
    }
 
    public String getPart1() {
       return part1;
    }
 
    public String getPart2() {
       return part2;
    }
 
    public String getPart3() {
       return part3;
    }
 }
 
 public interface Builder {
    public void buildPart1(String part1);
    public void buildPart2(String part2);
    public void buildPart3(String part3);
    public Product getProduct();
 }
 
 public class ConcreteBuilder implements Builder {
    private Product product = new Product();
 
    public void buildPart1(String part1) {
       product.setPart1(part1);
    }
 
    public void buildPart2(String part2) {
       product.setPart2(part2);
    }
 
    public void buildPart3(String part3) {
       product.setPart3(part3);
    }
 
    public Product getProduct() {
       return product;
    }
 }
 
 public class Director {
    private Builder builder;
 
    public Director(Builder builder) {
       this.builder = builder;
    }
 
    public void construct() {
       builder.buildPart1("Part 1");
       builder.buildPart2("Part 2");
       builder.buildPart3("Part 3");
    }
 }
 
 public class Main {
    public static void main(String[] args) {
       Builder builder = new ConcreteBuilder();
       Director director = new Director(builder);
       director.construct();
       Product product = builder.getProduct();
 
       System.out.println(product.getPart1());
       System.out.println(product.getPart2());
       System.out.println(product.getPart3());
    }
 }

In this example, we have a Product class that we want to create using the Builder Pattern. We have a Builder interface with methods for creating the different parts of the product. We also have a ConcreteBuilder class that implements the Builder interface and provides methods for creating the different parts of the product. The ConcreteBuilder class is responsible for constructing the product step by step. We have a Director class that controls the building process using a builder object. The Director is responsible for coordinating the construction of the product.

In the Main class, we create a ConcreteBuilder object and pass it to the Director. The Director then uses the ConcreteBuilder object to construct the Product object. Finally, we get the Product object and print its different parts.

The Builder Pattern provides a flexible and reusable solution for creating complex objects. It separates the construction of the object from its representation, making it easier to create different representations of the same object. It also allows us to add new features to the product without affecting its construction process.

In conclusion, the Builder Pattern is a useful design pattern for creating complex objects that involve multiple steps. By using a builder object to construct the object step by step, we can create different representations of the same object and add new features without affecting its construction process.