This is the 8th day of my participation in the More text Challenge. For details, see more text Challenge
Wechat official account: Xiao Lei
When you work hard to a certain extent, luck will meet you accidentally.
First, know the builder model
1.1 an overview of the
Today, we’ll look at the last of the creator patterns: The Builder pattern.
First go to Baidu Encyclopedia:
The builder pattern is a design pattern that separates the construction of a complex object from its representation, allowing the same construction process to create different representations.
How do you understand that?
This definition has three key points:
- Complex object
- Build and presentation are separated
- The same build can create different representations
First, the Builder pattern is suitable for complex objects. What are the characteristics of this complex object? When the object is built from multiple parts, and the object is difficult to build. So, the idea of separation of build and representation is, different build, same assembly, and this is decoupling of build and assembly. The same build can create different representations, that is, the client can perform the same steps and get different representations. For example, when we buy food from a group, we only need to place an order after we have selected the food. For the customer, this step is fixed, while the deliveryman will assemble these components step by step according to the customer’s requirements.
1.2 Application Scenarios
- When a class has more than four constructor arguments, and some of those arguments are optional, consider using the builder pattern.
- The objects created are complex, consisting of multiple components that face complex changes, but the building sequence between components is stable.
- The Builder pattern is not suitable for creating very diverse product classes
- The build and final presentation of the product are independent.
Second, the realization of the builder model
2.1 structure
The Builder mode contains the following roles:
- Abstract Builder: This interface specifies which parts of a complex object to implement, and does not involve the creation of concrete part objects.
- ConcreteBuilder: Implements the Builder interface to complete the concrete method of creating each part of a complex product. After the construction process is complete, provide an instance of the product.
- Product class: Complex object to create
- The Director class: calls the concrete builder to create the parts of a complex object. The Director has no product-specific information, but is responsible for ensuring that the parts of the object are created completely or in some order.
2.2 example
Since it’s the builder model, let’s take building construction as an example. It can be divided into villas and roofedhouses.
Building a building is a complex process, assuming that three materials are required: rebar, cement and brick.
2.2.1 Defining product classes
(1) Define the house entity class
Public class House {// private String rebar; // Private String cement; // Private String brick; public String getRebar() { return rebar; } public void setRebar(String rebar) { this.rebar = rebar; } public String getCement() { return cement; } public void setCement(String cement) { this.cement = cement; } public String getBrick() { return brick; } public void setBrick(String brick) { this.brick = brick; } @Override public String toString() { return "House{" + "rebar='" + rebar + '\'' + ", cement='" + cement + '\'' + ", brick='" + brick + '\'' + '}'; }}Copy the code
2.2.2 Define the abstract Builder class
public abstract class HouseModel {
protected House house = new House();
public abstract void buildRebar();
public abstract void buildCement();
public abstract void buildBrick();
public abstract House createHouse();
}
Copy the code
2.2.3 Define concrete builder classes
Public class VillaHouse extends HouseModel{@override public void buildRebar() {house.setrebar (); } @override public void cement () {house.setcement (); } @override public void buildBrick() {house.setbrick (" national red brick "); } @Override public House createHouse() { return house; }}Copy the code
Public class RoofedHouse extends HouseModel{@override public void buildRebar() {house.setrebar (); } @override public void cement () {house.setcement (); } @override public void buildBrick() {house.setbrick (" earth brick "); } @Override public House createHouse() { return house; }}Copy the code
2.2.4 Define the director class
public class Director { private HouseModel model; public Director(HouseModel houseModel){ this.model=houseModel; } public House construct(){ model.buildBrick(); model.buildRebar(); model.buildCement(); return model.createHouse(); }}Copy the code
2.2.5 test
public class Client { public static void main(String[] args) { showHouse(new VillaHouse()); showHouse(new RoofedHouse()); } private static void showHouse(HouseModel houseModel){ Director director = new Director(houseModel); House house = director.construct(); System.out.println(house.toString()); }}Copy the code
Print result:
House{rebar=' cement ', brick=' national red brick '} House{rebar=' rusty steel ', cement=' non-sticky cement ', brick=' clay brick '}Copy the code
The Director class plays an important role in the builder pattern as it guides specific builders on how to build a product, controls the order of calls, and returns a complete product class to the caller.
2.3 the advantages and disadvantages
2.3.1 advantages
- The builder pattern encapsulates well. Using the builder pattern can effectively encapsulate changes and achieve better overall stability.
- In the builder pattern, the client does not have to know the details of the internal composition of the product, and the product itself is decoupled from the creation process of the product, allowing the same creation process to create different product objects.
- You can control the product creation process more finely. Breaking down the creation steps of complex products into different approaches makes the creation process clearer and easier to control programmatically
- The builder pattern is easy to extend. If there is a new requirement, it can be accomplished by implementing a new builder class, consistent with the open closed principle.
2.3.2 shortcomings
- The builder pattern typically creates products that have more in common and whose components are similar, and is not appropriate if there are significant differences between products.
Third, other applications of the builder model
3.1 Multi-parameter code refactoring
The builder pattern can also be used to refactor code with multiple parameters. With the freedom to combine parameters, the design of the builder pattern is generally complex and flexible.
public class Phone { private String cpu; private String screen; private String memory; private String mainboard; public Phone(String cpu, String screen, String memory, String mainboard) { this.cpu = cpu; this.screen = screen; this.memory = memory; this.mainboard = mainboard; } public String getCpu() { return cpu; } public void setCpu(String cpu) { this.cpu = cpu; } public String getScreen() { return screen; } public void setScreen(String screen) { this.screen = screen; } public String getMemory() { return memory; } public void setMemory(String memory) { this.memory = memory; } public String getMainboard() { return mainboard; } public void setMainboard(String mainboard) { this.mainboard = mainboard; } @Override public String toString() { return "Phone{" + "cpu='" + cpu + '\'' + ", screen='" + screen + '\'' + ", memory='" + memory + '\'' + ", mainboard='" + mainboard + '\'' + '}'; }} public class Client {public static void main(String[] args) {// Build the Phone object Phone = new Phone(" Intel "," Samsung Screen "," Kingston "," Asus "); System.out.println(phone); }}Copy the code
public class Phone { private String cpu; private String screen; private String memory; private String mainboard; private Phone(Builder builder) { cpu = builder.cpu; screen = builder.screen; memory = builder.memory; mainboard = builder.mainboard; } public static final class Builder { private String cpu; private String screen; private String memory; private String mainboard; public Builder() {} public Builder cpu(String val) { cpu = val; return this; } public Builder screen(String val) { screen = val; return this; } public Builder memory(String val) { memory = val; return this; } public Builder mainboard(String val) { mainboard = val; return this; } public Phone build() { return new Phone(this); } } @Override public String toString() { return "Phone{" + "cpu='" + cpu + '\'' + ", screen='" + screen + '\'' + ", memory='" + memory + '\'' + ", mainboard='" + mainboard + '\'' + '}'; } } public class Client { public static void main(String[] args) { Phone phone = new Phone.Builder() .cpu("intel") Mainboard (" asus "). The memory (" Kingston "). The screen (" samsung "). The build (); System.out.println(phone); }}Copy the code
3.2 Builder pattern applied in JDK
A familiar interview question in my mind is what is the difference between a stringBuffer and a StringBuilder. The difference is that StringBuilder is thread-unsafe and StringBuffer is thread-safe. And this StringBuilder uses the builder pattern.
Appendable defines abstract methods for the abstract builder class
public interface Appendable {
Appendable append(CharSequence csq) throws IOException;
Appendable append(CharSequence csq, int start, int end) throws IOException;
Appendable append(char c) throws IOException;
}
Copy the code
AbstractStringBuilder implements all append () methods of the Appendable interface method
abstract class AbstractStringBuilder implements Appendable, CharSequence {
}
Copy the code
StringBuilder acts as both the conductor and the concrete builder. Returns the this object itself as the product class.
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence { @Override public StringBuilder append(String str) { super.append(str); return this; }}Copy the code
Four, summary
This article explains the concept of the builder pattern and simple implementation, can only do a simple introduction, the real builder pattern in the source code application is very complex, can only say that there is a chance to go further, entry, this article is enough, this is also a brief talk about the design pattern to achieve the purpose. Here’s a quick summary of what we’ve learned in the last few days about creation patterns.
The difference between the builder pattern and the factory pattern is that the builder pattern focuses on the process of building components, building a complex object step by step. The factory method focuses on how the overall object is created.
Creation pattern classification:
- Singleton pattern: A class that generates only one instance, provides a global point of access for external access to that instance, and extends the finite multiinstance pattern.
- The Prototype pattern: Take an object as a Prototype and copy it to clone multiple new instances similar to the Prototype.
- FactoryMethod pattern: Defines an interface for creating a product, with subclasses deciding what product to produce.
- AbstractFactory pattern: provides an interface for creating a family of products, each subclass of which can produce a set of related products.
- Builder pattern: A complex object is broken down into relatively simple parts, then each is created for different needs, and then the complex object is built.