Builder pattern common examples
Today, a simple and rough introduction to the concept of Builder mode and use.
- The creation of a Dialog
AlertDialog dialog = new AlertDialog.Builder(this)
.setIcon(R.mipmap.ic_launcher)
.setMessage("Hello World")
.setTitle("Dialog")
.create(a);
dialog.show(a);Copy the code
- Creation of the OkHttp Request
Request request = new Request.Builder()
.url("https://github.com/hongyangAndroid")
.build();Copy the code
Benefits/advantages of Builder mode
The usability and readability of the client code is greatly improved. At the same time, the number of arguments to the constructor is significantly reduced and is very straightforward to call. Ic_launcher (“Hello World”,” dialog “,”How are you”); While improving code readability, it is also easier to use the code completion features provided by the IDE.
Builder example
Here’s an example of chestnuts ordered at McDonald’s
public class McFood {
private int totalCount; / / copies
private boolean addIce; // Is the drink deiced
private Hamburg hamburg; / / hamburger
private Drink drink; / / drinks
private String remark; / / note
private boolean takeOut; // Is it to go
public static class Hamburg {// Hamburgers
public static final String HAMBURG_CHICKEN = "chicken";
public static final String HAMBURG_BEEF = "beef";
public Hamburg(String hamburgName) {
this.hamburgName = hamburgName;
}
public String getHamburgName() {
return hamburgName;
}
private String hamburgName;
}
public static class Drink {/ / drinks
public static final String DRINK_COLA = "cola";
public static final String DRINK_SPRITE = "sprite";
public Drink(String drinkName) {
this.drinkName = drinkName;
}
private String drinkName;
public String getDrinkName() {
returndrinkName; }}}Copy the code
Introduction of the Builder class to enhance client usability and readability
public static class Builder {
private int totalCount = 0;
private boolean addIce = false;
private Hamburg hamburg = null;
private Drink drink = null;
private String remark = null;
private boolean takeOut = false;
public Builder totalCount(int totalCount) {
this.totalCount = totalCount;
return this;
}
public Builder addIce(boolean addIce) {
this.addIce = addIce;
return this;
}
public Builder hamburg(Hamburg hamburg) {
this.hamburg = hamburg;
return this;
}
public Builder drink(Drink drink) {
this.drink = drink;
return this;
}
public Builder remark(String remark) {
this.remark = remark;
return this;
}
public Builder takeOut(boolean takeOut) {
this.takeOut = takeOut;
return this;
}
public McFood create() { // Build, return a new object
return new McFood(this); }}Copy the code
Of course, you also need to set the construction method of McFood.
public McFood(Builder builder) {
this.totalCount = builder.totalCount;
this.addIce = builder.addIce;
this.hamburg = builder.hamburg;
this.drink = builder.drink;
this.remark = builder.remark;
this.takeOut = builder.takeOut;
}Copy the code
Finally, let’s look at how the client operates
McFood food = new McFood.Builder()
.drink(new Drink(DRINK_COLA))
.addIce(false) / / to ice
.hamburg(new Hamburg(HAMBURG_BEEF)) // Beef burger
.takeOut(true) / / to go
.totalCount(3) / / * 3 in total
.create(a);Copy the code
After looking at the code verdict, the client code that calls a traditional JAVA constructor is much less readable than the client code that uses Builder. The same type of variable and null called together can cause subtle errors. If the client accidentally reverses the order of several of these arguments, it will compile correctly but will certainly fail at runtime.
Disadvantages of Builder mode
Using Builder mode is a surefire way to increase the amount of code. In addition, while client-side code readability has improved significantly, the resulting client-side code has become more verbose. But the former is more valuable.
Builder adds a class code, which means developers sometimes forget to add supported Builders to a class when adding properties to that class. To overcome this problem, builders are often nested into classes so that it is easy to discover which related Builder needs to be updated. While the risk of forgetting is still there, it’s like forgetting to add toString(), equals(Object), hashCode(), or any other class based method to a new property of a class.
conclusion
Builder mode is recommended when you encounter a class that has many arguments, many of which are of the same type and many of which can be null. When the number of parameters is small, the types are different, and they all have to be present, implementing a Builder by adding code often fails to take advantage of it. In this case, the ideal approach is to call the traditional constructor. Again, if you don’t need to be invariant, call the corresponding set method using the no-argument constructor.