This article is participating in the Java Theme Month – Java Debug Notes Event, see the event link for details

Question: When is the Builder mode used?

What are some real-world examples of the Builder pattern? What does it do? Why not just use factory mode

Answer a

Here are some reasons to use this pattern and sample Java code, but it is implemented by the Builder pattern, which was discussed by the four people who designed the pattern. You can use these principles in Java as well as in other programming languages

As Joshua Bloch put it in the second edition of Effective Java:

The builder pattern is a good choice when designing a class whose constructor or static factory has a lot of arguments

We’ve all come across a class that has a bunch of constructors, and each argument list just adds one argument

Pizza(int size) { ... }        
Pizza(int size, boolean cheese) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni) { ... }    
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }
Copy the code

This is called the overlapping constructor pattern. The problem with this pattern is that once you have 4 or 5 arguments, it’s hard to remember the order of arguments and which constructor to use in this case

One alternative to the overlapping constructor pattern is the Javabean pattern, where you can call a constructor with mandatory arguments and any setter method you want to call.

Pizza pizza = new Pizza(12);
pizza.setCheese(true);
pizza.setPepperoni(true);
pizza.setBacon(true);
Copy the code

The problem here is that the object takes several calls to create, and inconsistencies can occur during construction. This requires some additional work to ensure thread-safety.

A better choice would be to use the Builder mode

public class Pizza {
  private int size;
  private boolean cheese;
  private boolean pepperoni;
  private boolean bacon;

  public static class Builder {
    //required
    private final int size;

    //optional
    private boolean cheese = false;
    private boolean pepperoni = false;
    private boolean bacon = false;

    public Builder(int size) {
      this.size = size;
    }

    public Builder cheese(boolean value) {
      cheese = value;
      return this;
    }

    public Builder pepperoni(boolean value) {
      pepperoni = value;
      return this;
    }

    public Builder bacon(boolean value) {
      bacon = value;
      return this;
    }

    public Pizza build(a) {
      return new Pizza(this); }}private Pizza(Builder builder) { size = builder.size; cheese = builder.cheese; pepperoni = builder.pepperoni; bacon = builder.bacon; }}Copy the code

Pizza is invariant, and the values of all parameters are in the same place, because setter methods of Builder put back a Builder object, so they can be connected as follows:

Pizza pizza = new Pizza.Builder(12)
                       .cheese(true)
                       .pepperoni(true)
                       .bacon(true)
                       .build();
Copy the code

The article translated from Stack Overflow:stackoverflow.com/questions/3…