1 Overview
As we said earlier Factory Mode and Abstract Factory Mode , let's talk about the builder model. The builder mode is also a very common creation mode. The two factory modes mentioned earlier hide the properties and construction details of a class, while the builder mode exposes the properties of a class appropriately through the Builder class, making class creation more flexible and readable.
2 Builder Mode
When a class's constructor contains many parameters, or there are many combinations of parameters (such as a Kentucky package), calling the constructor to create the class becomes inconvenient and less readable.Factory mode will also become inappropriate for multiple combinations. In this case, the builder pattern provides an idea to greatly simplify the complexity of class creation by delegating class creation to the builder, which separates class creation from representation.
3 Cases
Consider making a Pizza, which for convenience only contains four attributes: size, base, filling and whether to add cheese.See how to create using the Builder mode:
public class Test { public static void main(String[] args) { Pizza.Builder pizzaBuilder = new Pizza.Builder(); Pizza pizza = pizzaBuilder.size(6) .crustType(Pizza.CrustType.THIN) .topping("Durian") .build(); pizza.info(); } } public class Pizza { private int size;// inch private CrustType crustType; private String topping; private boolean cheese;// optional private Pizza(Builder builder) { if (builder.size <= 0) { throw new IllegalStateException("Invalid pizza size."); } if (builder.crustType == null) { throw new IllegalStateException("Invalid pizza crust type."); } if (builder.topping == null) { throw new IllegalStateException("Invalid pizza topping."); } this.size = builder.size; this.crustType = builder.crustType; this.topping = builder.topping; this.cheese = builder.cheese; } public void info() { System.out.println("Pizza size: " + size + ", crust type: " + crustType + ", topping: " + topping + ", with cheese: " + cheese); } public static enum CrustType { THIN, THICK } // inner class to build Pizza public static class Builder { private int size; private CrustType crustType; private String topping; private boolean cheese = false; public Builder size(int size) { this.size = size; return this; } public Builder crustType(CrustType crustType) { this.crustType = crustType; return this; } public Builder topping(String topping) { this.topping = topping; return this; } public Builder cheese(boolean cheese) { this.cheese = cheese; return this; } public Pizza build() { return new Pizza(this); } } }
Output:
Pizza size: 6, crust type: THIN, topping: Durian, with cheese: false
UML:
First, the constructor for the class is privateized, and class creation can only be done through Pizza.Builder.Pizza.Builder's process of creating a class is actually a process of customizing the class and gradually setting its properties.Chained calls make it easy and intuitive to add required attributes to a class, which is highly scalable.What type of Pizza you want to create is entirely up to the caller.
The builder model is very common. as Calendar.Builder Provides a way to customize the construction of Calendar. as StringBuilder String objects can be constructed dynamically and flexibly.Similarly, there are MyBatis's AbstractSQL To construct a complete SQL statement step by step in an intuitive way.
4 Summary
When a class has many attributes, or when there are multiple combinations of attributes (Calendar.Builder), or when an object maintains a state that requires progressive invocation of methods to complete the state (StringBuilder), consider using the Builder mode.