Brief introduction
Basic concepts
- Builder Pattern, also known as Generator Pattern, is an object-building pattern. It can abstract the construction process of complex objects (abstract categories) so that different implementations of this abstract process can construct objects with different representations (attributes).
- Builder mode is a step-by-step process for creating complex objects that allows users to build complex objects simply by specifying their type and content, without needing to know the specific building details inside.
4 Roles
Product: A specific product object
Builder: Creates an interface/abstract class specified by each part of a Product Object.
ConcreteBuilder: Implement interfaces, build and assemble components.
Director: Build an object that uses 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, the other is to control the production process of product objects.
Build mode then we certainly associate building a house, so we use an example of building a house to compare the traditional writing with the builder mode writing
The requirements are as follows:
1. Need to build a house: this process is piling, wall building, roofing
2. There are all kinds of houses, such as ordinary houses, high buildings, villas and all kinds of houses. Although the process is the same, the requirements are not the same.
Traditional Writing
public abstract class AbstractHouse { //Foundation beating public abstract void buildBasic(); //Masonry wall public abstract void buildWalls(); //Top Cover public abstract void roofed(); public void build() { buildBasic(); buildWalls(); roofed(); } }
public class CommonHouse extends AbstractHouse { @Override public void buildBasic() { // TODO Auto-generated method stub System.out.println(" Foundation for ordinary houses "); } @Override public void buildWalls() { // TODO Auto-generated method stub System.out.println(" Ordinary house walls "); } @Override public void roofed() { // TODO Auto-generated method stub System.out.println(" Ordinary house roof "); } }
public class Client { public static void main(String[] args) { CommonHouse commonHouse = new CommonHouse(); commonHouse.build(); } }
Advantages and disadvantages analysis
- The advantage is that it is easy to understand and operate.
- The design of the program structure is too simple, there is no design cache layer object, the program expansion and maintenance is not good. In other words, this design scheme encapsulates the product (i.e., the house) and the process of creating the product (i.e., the building process) together, which enhances the coupling.
- Solution: Decouple product and product construction =>Builder mode.
Builder pattern
Product->Product
public class House { private String baise; private String wall; private String roofed; }
Abstract builder
public abstract class HouseBuilder { protected House house = new House(); //Write the process of construction, abstract method public abstract void buildBasic(); public abstract void buildWalls(); public abstract void roofed(); //Build a house and return the product (house) public House buildHouse() { return house; } }
Commander, go here to specify the production process and return to the product
public class HouseDirector { HouseBuilder houseBuilder = null; //Constructor passed into houseBuilder public HouseDirector(HouseBuilder houseBuilder) { this.houseBuilder = houseBuilder; } //Pass in houseBuilder via setter public void setHouseBuilder(HouseBuilder houseBuilder) { this.houseBuilder = houseBuilder; } //How to handle the process of building a house and give it to the commander public House constructHouse() { houseBuilder.buildBasic(); houseBuilder.buildWalls(); houseBuilder.roofed(); return houseBuilder.buildHouse(); } }
Ordinary house
public class CommonHouse extends HouseBuilder { @Override public void buildBasic() { // TODO Auto-generated method stub System.out.println(" Plain house with 5 meters Foundation "); } @Override public void buildWalls() { // TODO Auto-generated method stub System.out.println(" Ordinary house wall 10 cm "); } @Override public void roofed() { // TODO Auto-generated method stub System.out.println(" Ordinary house roof "); } }
Tall building
public class HighBuilding extends HouseBuilder { @Override public void buildBasic() { // TODO Auto-generated method stub System.out.println(" 100 meters of high building foundation "); } @Override public void buildWalls() { // TODO Auto-generated method stub System.out.println(" High-rise masonry wall 20 cm "); } @Override public void roofed() { // TODO Auto-generated method stub System.out.println(" Transparent roof of tall building "); } }
public class Client { public static void main(String[] args) { //Build a regular house CommonHouse commonHouse = new CommonHouse(); //Commander preparing to build a house HouseDirector houseDirector = new HouseDirector(commonHouse); //Finish building the house and return to the product (regular house) House house = houseDirector.constructHouse(); //System.out.println("Output Process"); System.out.println("--------------------------"); //Tower Build HighBuilding highBuilding = new HighBuilding(); //Reset Builder houseDirector.setHouseBuilder(highBuilding); //Finish building the house and return to the product (tall building) houseDirector.constructHouse(); } }
Considerations and details for the builder model
- Clients (users) do not have to know the details of the internal composition of the product to decouple the product itself from the creation process so that the same creation process can create different product objects
- Each individual builder is relatively independent and independent of other specific builders, so it is easy to replace or add new specific builders, and users can get different product objects from different specific builders.
- You can control the process of creating a product more finely. Decomposition the creation steps of complex products into different methods to make the creation process clearer and easier to use programs to control the creation process
- Adding new concrete builders without modifying the code of the original class library. The commander class is programmed for the abstract builder class. The system is easy to expand and complies with the Open and Close Principle.
- Builder modes generally create products with many common features and similar components. Builder modes are not suitable for use if the differences between products are large, so the scope of use is limited.
- If the internal variation of the product is complex, it may result in the need to define many specific builder classes to achieve this change, resulting in a very large system, so in this case, consider whether or not to choose the builder mode.
Abstract Factory Mode VS Builder Mode
The abstract factory model implements the creation of product family, a product family is a series of products: product combinations with different classification dimensions, using the abstract factory model does not need to care about the construction process, only what products are produced by which factory. The builder model requires that products be built according to a specified blueprint, and its primary purpose is to produce a new product by assembling spare parts. In general, the difference from the factory model is that the builder model pays more attention to the order in which parts are assembled.
Application of Builder Mode in JDK
Builder mode in java.lang.StringBuilder
- The Appendable interface defines several append methods (abstract methods), that is, Appendables are abstract builders and define abstract methods
- AbstractStringBuilder implements the Appendable interface method, where AbstractStringBuilder is already the builder but cannot be instantiated
- StringBuilder acts as both a commander and a specific builder, the implementation of which is accomplished by AbstractStringBuilder, which inherits AbstractStringBuilder
StringBuilder is not a standard builder model, however, because there was no design mode when StringBuilder was created.