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…