Illustrating the builder pattern of Java design pattern

Illustrating the builder pattern of Java design pattern

Building project demand

1) Need to build houses: this process involves piling, walling and capping
2) There are various kinds of houses, such as ordinary houses, high-rise buildings, villas. Although the process of various houses is the same, the requirements are not the same.

Traditional way to solve the housing demand

1) Thought analysis (illustration)

package com.example.demo.builder;

public abstract class AbstractHouse {
	
	/**
	 * Lay the foundation
	 */
	public abstract void buildBasic();

	/**
	 * Masonry wall
	 */
	public abstract void buildWalls();
	
	/**
	 * Capping
	 */
	public abstract void roofed();
	
	public void build() {
		buildBasic();
		buildWalls();
		roofed();
	}
}
package com.example.demo.builder;

public class CommonHouse extends AbstractHouse{

	@Override
	public void buildBasic() {
		// TODO Auto-generated method stub
		System.out.println(" Common house foundation ");
	}

	@Override
	public void buildWalls() {
		// TODO Auto-generated method stub
		System.out.println(" Building walls in ordinary houses ");
	}

	@Override
	public void roofed() {
		// TODO Auto-generated method stub
		System.out.println(" Common house capping ");
	}

}
package com.example.demo.builder;

public class Client {
	public static void main(String[] args) {
		AbstractHouse abstractHouse = new CommonHouse();
		abstractHouse.build();
	}
}

An analysis of the problems in the traditional way

1) The advantages are easy to understand and operate.
2) The designed program structure is too simple, there is no cache layer object designed, and the extension and maintenance of the program is not good. That is to say, this design scheme encapsulates the product (i.e. house) and the process of creating the product (i.e. house building process), which enhances the coupling.
3) Solution: decouple the product and product construction process = builder mode.

Basic introduction of builder mode

Basic introduction
1) 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 implementation methods of the abstract process can construct different objects (properties).
2) Builder mode is to create a complex object step by step, which allows users to build complex objects only by specifying their types and contents. Users do not need to know the specific construction details inside.

Four roles of builder model

1) Product: a specific product object.
2) Builder: creates an interface / abstract class specified by each part of a Product object.
3) Concrete Builder: implement interfaces, build and assemble components.
4) Director: build an object that uses the Builder interface. It is mainly used to create a complex object. It has two functions: one is to isolate the production process of customers and objects; the other is to control the production process of product objects.

Principle class diagram of builder mode

package com.example.demo.builder.improve;

/**
 * Product s
 * @author zhaozhaohai
 *
 */
public class House {
	private String baise;
	private String wall;
	private String roofed;
	public String getBaise() {
		return baise;
	}
	public void setBaise(String baise) {
		this.baise = baise;
	}
	public String getWall() {
		return wall;
	}
	public void setWall(String wall) {
		this.wall = wall;
	}
	public String getRoofed() {
		return roofed;
	}
	public void setRoofed(String roofed) {
		this.roofed = roofed;
	}
	
}
package com.example.demo.builder.improve;

/**
 * Abstract builder
 * @author zhaozhaohai
 *
 */
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();
	
	/**
	 * After building the house, return the house (product),
	 */
	public House buildHouse() {
		return house;
	}
}
package com.example.demo.builder.improve;

public class CommonHouse extends HouseBuilder{

	@Override
	public void buildBasic() {
		// TODO Auto-generated method stub
		System.out.println(" Common house foundation 5m ");
	}

	@Override
	public void buildWalls() {
		// TODO Auto-generated method stub
		System.out.println(" Common house wall 10 cm ");
	}

	@Override
	public void roofed() {
		// TODO Auto-generated method stub
		System.out.println(" Common house roof ");
	}

}
package com.example.demo.builder.improve;

public class HighHouse extends HouseBuilder{

	@Override
	public void buildBasic() {
		// TODO Auto-generated method stub
		System.out.println(" The foundation of the high building is 100m ");
	}

	@Override
	public void buildWalls() {
		// TODO Auto-generated method stub
		System.out.println(" 50 meters high building ");
	}

	@Override
	public void roofed() {
		// TODO Auto-generated method stub
		System.out.println(" The transparent roof of a tall building ");
	}

}
package com.example.demo.builder.improve;

/**
 * Commander, specify the process and return to the product
 * @author zhaozhaohai
 *
 */
public class HouseDirector {
	private HouseBuilder houseBuilder = null;
	
	/**
	 * Constructor passed in to houseBuilder
	 * @param houseDirector
	 */
	public HouseDirector(HouseBuilder houseBuilder) {
		this.houseBuilder = houseBuilder;
	}

	/**
	 * Pass in houseBuilder through setter
	 * @param houseDirector
	 */
	public void setHouseDirector(HouseBuilder houseBuilder) {
		this.houseBuilder = houseBuilder;
	}
	
	/**
	 * How to deal with the process of building a house, give it to the commander
	 * @return
	 */
	public House construHouse() {
		houseBuilder.buildBasic();
		houseBuilder.buildWalls();
		houseBuilder.roofed();
		return houseBuilder.buildHouse();
	}
	
}
package com.example.demo.builder.improve;

public class Client {
	public static void main(String[] args) {
		// Build a common house
		CommonHouse commonHouse = new CommonHouse();
		// The conductor who is going to build the house
		HouseDirector houseDirector = new HouseDirector(commonHouse);
		
		// Finish building house, return product (house)
		House house = houseDirector.construHouse();
	}
}

Application and source code analysis of builder mode in JDK

1) Builder pattern in java.lang.StringBuilder




2) Analysis of the role of builder pattern in source code
(1) The Appendable interface defines multiple append methods (abstract methods), that is, Appendable is the abstract builder and defines abstract methods
(2) AbstractStringBuilder implements the Appendable interface method. The AbstractStringBuilder here is already a builder, but it cannot be instantiated
(3) StringBuilder is the role of commander and acts as the specific builder. The implementation of the construction method is completed by AbstractStringBuilder, which inherits AbstractStringBuilder

Notes and details of builder mode

1) The client (user program) does not need to know the details of the internal components of the product, decouples the product itself from the creation process of the product, so that the same creation process can create different product objects
2) Each specific builder is relatively independent, and has nothing to do with other specific builders. Therefore, it is very convenient to replace specific builders or add new specific builders. Users can get different product objects by using different specific builders
3) You can control the product creation process more precisely. Decompose the creation steps of complex products into different methods, making the creation process clearer and easier to use the program to control the creation process
4) Adding a new specific builder does not need to modify the code of the original class library. The commander class is programmed for the abstract builder class. The system is easy to expand and conforms to the "open close principle"
5) The products created by the builder mode generally have more common points, and their components are similar. If there is a large difference between products, it does not conform to the use of the builder mode, so its use scope is limited.
6) If the internal change of the product is complex, it may lead to the need to define many specific builder classes to achieve this change, resulting in a very large system. Therefore, in this case, it is necessary to consider whether to choose builder mode.
7) Abstract factory mode VS builder mode
Abstract factory pattern realizes the creation of product family. A product family is such a series of products. For the product portfolio with different classification dimensions, using abstract factory pattern does not need to care about the construction process, but only about what products are produced by what factory. The builder mode is to build products according to the specified blueprint, and its main purpose is to produce a new product by assembling parts.

143 original articles published, 32 praised, 20000 visitors+
Private letter follow

Keywords: Java JDK

Added by Amitk on Mon, 09 Mar 2020 05:09:43 +0200