Specific needs
Demand for building a house:
- Need to build a house: this process is piling, building walls and capping
- There are all kinds of houses, such as ordinary houses, high-rise buildings, villas. Although the process of all kinds of houses is the same, the requirements are different.
Traditional ways to solve problems:
Analysis of traditional ways to solve the problem of building demand:
- The designed program structure is too simple, there is no cache layer object, and the program expansion and maintenance are not good In other words, this design scheme encapsulates the product (i.e. house) and the process of creating the product (i.e. house building process), and the coupling is enhanced.
- Solution: decouple product and product construction process = > builder mode
The four roles of the builder model
- Product role: a specific product object
- Builder (Abstract builder): create an interface / abstract class specified by each part of a Product object.
- Cuncrete Builder: implement interfaces, build and assemble various components
- Diector (director): build an object using the Builder interface. It is mainly used to create a complex object. It has two main functions: one is to isolate the production process of customers and objects, and the other is to control the production process of product objects.
Building improvement of builder mode
Commander
public class HouseDirector { Builder builder = null; //Constructor incoming public HouseDirector(Builder builder) { this.builder = builder; } //Passed in through the Set method public void setBuilder(Builder builder) { this.builder = builder; } //How to deal with the process of building a house and leave it to the commander public House constructHouse(){ builder.buildBasic(); builder.buildWalls(); builder.roofed(); return builder.buildHouse(); } }
Abstract builder
public abstract class Builder { protected House house = new House(); //Write the construction process and abstract method public abstract void buildBasic(); public abstract void buildWalls(); public abstract void roofed(); //Build a house and return the product public House buildHouse(){ return house; } }
Specific builder
public class CommonHouse extends Builder { @Override public void buildBasic() { System.out.println("Laying foundation for ordinary house"); house.setBasic("5"); } @Override public void buildWalls() { System.out.println("Ordinary house walling 10 cm"); house.setRoofed("10"); } @Override public void roofed() { System.out.println("Ordinary house capping"); house.setRoofed("10"); } }
client
public class Client { public static void main(String[] args) { //Ordinary house CommonHouse commonHouse = new CommonHouse(); //The commander ready to create the house HouseDirector houseDirector = new HouseDirector(commonHouse); House house = houseDirector.constructHouse(); System.out.println(house.getBasic()); System.out.println("-------------------"); //Building construction HighBuilding highBuilding = new HighBuilding(); houseDirector.setBuilder(highBuilding); House house1 = houseDirector.constructHouse(); } }
Source code analysis of builder pattern in JDK
java. Builder pattern in lang. StringBuilder
Application analysis of builder in JDK
- Analysis of the role of the builder pattern in the source code.
//The Appendable interface defines multiple append methods (abstract methods), that is, Appendable is the abstract builder and defines abstract methods
//AbstractStringBuilder implements the Appendable interface method. AbstractStringBuilder is already the builder, but it cannot be instantiated.
//Stringbuilder not only acts as a commander, but also acts as a specific builder. The implementation of the construction method is completed by AbstractStringBuilder, which inherits AbstractStringBuilder
Notes and details of builder mode
- The client (user program) does not need to know the internal composition details of the product, decouples the product itself from the product creation process, so that the same creation process can create different product objects.
- Each specific builder is relatively independent and has nothing to do with other specific builders. Therefore, it is convenient to replace specific builders or add new builders. Users can get different product objects by using different specific builders
- You can more finely control the product creation process. The creation steps of complex products are decomposed into different methods, which makes the creation process clearer and more convenient to use programs to control the creation process.
- Adding a new specific builder does not need to modify the code of the original class library. The commander programs for the abstract builder, which is convenient for system class expansion and conforms to the "opening and closing principle".
- The products created by the builder mode generally have more in common and their components are similar. If there are great differences between products, it is not suitable to use the builder mode, so its practical scope is limited.
- If the interior of the product becomes complex, it may lead to the need to define many specific builder classes to realize this change, resulting in a particularly large system. Therefore, in this case, it is necessary to consider whether to select the builder mode.
Abstract factory VS builder pattern
Abstract factory pattern realizes the creation of product family. A product family is such a series of products; For product combinations with different classification dimensions, the abstract factory model does not need to care about the construction process, but only about what products are produced by what factory. The builder model requires the product to be built according to the specified blueprint. Its main purpose is to produce a new product by assembling spare parts.