preface
As we know, common design patterns are usually divided into three categories: creative patterns, behavioral patterns and structural patterns. Today, let's talk about the builder mode in the creation mode, about its use scenarios, advantages and disadvantages, components, practical examples and its application in JDK.
We are already familiar with the factory pattern, which is mainly used to extract instantiated objects and put them into a class for unified maintenance and management, so as to achieve decoupling and improve the scalability and maintainability of the project. The function of the builder mode is very similar to that of the factory mode, but the focus is different. Let's take a closer look at the creator model.
Introduction to builder mode
Builder Pattern, also translated as Builder Pattern, is also popularly called Builder Pattern. The official definition is to separate the construction of a complex object from its representation, so that the same construction process can create different representations.
In vernacular, it is to decompose a complex object into multiple simple objects, and then build it step by step to form a product. It mainly separates the changing part from the unchanged part, that is, the components of the product are unchanged, but each part can be flexibly selected.
For example, if we want to assemble a computer, we need CPU, motherboard, memory, hard disk, graphics card, chassis, display, keyboard, mouse and other components. These components are unchanged, but different configurations of each part can be selected according to their own economic conditions and use scenarios.
The construction of such a complex object often requires multiple steps. Moreover, the hardware configuration information used in each step may be different. At the same time, not every computer needs a monitor or mouse. Before we demonstrate the above scenario through code, let's take a look at several roles and functions usually included in the builder pattern.
Structure and function
The builder model usually consists of four roles: product, abstract builder, concrete builder and commander.
The functions of each role are as follows:
- Product role: the specific product object to be created, usually a complex object containing multiple components.
- Abstract Builder: an interface or abstract class used to create a product object, which contains abstract methods to create various sub parts of the product and methods to return the final object.
- Concrete Builder: implement the builder interface to complete the construction and assembly of different complex products.
- Director: build an object using the Builder interface to complete the creation of complex objects. It is responsible for controlling the production process of product objects and isolating the generation process of users and objects. No product specific information is involved in the commander.
The structure diagram is shown in the figure:
Implementation of pattern
As developers, when we use notebooks, we often configure external keyboard, mouse and external display. At this time, a complete set of computer equipment includes: laptop, mouse, keyboard and monitor. Of course, according to individual needs, some people don't need a mouse, some people don't need an external keyboard, and some people don't need an external display, which constitutes different products.
First, define the product Computer, that is, develop the overall configuration of the Computer:
public class Computer { /** * Notebook computer */ private Laptop laptop; /** * mouse */ private Mouse mouse; /** * monitor */ private Screen screen; /** * keyboard */ private Keyboard keyboard; public void show() { System.out.println("Notebook configuration:" + laptop.getName()); System.out.println("Mouse configuration:" + mouse.getName()); System.out.println("Display configuration:" + screen.getName()); System.out.println("Keyboard configuration:" + keyboard.getName()); } // Omit getter/setter methods }
The product consists of four components: laptop, mouse, monitor and keyboard.
Abstract Builder: contains the abstract method of creating each sub part of the product. Declare the product construction steps common in all type generators through the interface.
public interface ComputerBuilder { /** * Building laptops */ void constructLaptop(); /** * Build mouse */ void constructMouse(); /** * Build screen */ void constructScreen(); /** * Build keyboard */ void constructKeyboard(); /** * Return end product object */ Computer getResult(); }
The abstract builder provides a unified method for the construction of each component. As for the specific internal configuration of each component, there may be various changes, which can be implemented by a specific implementer.
Concrete Builder: implements the abstract builder interface. In the current business scenario, we assume that there are two types of computer configurations given by the company, one is ordinary configuration and the other is high-end configuration. In this way, there are two specific builders to provide different implementations of the construction process.
Common configuration implementation:
public class CommonComputerBuilder implements ComputerBuilder { private Computer computer = new Computer(); @Override public void constructLaptop() { Laptop laptop = new Laptop("A","Huawei notebook"); computer.setLaptop(laptop); } @Override public void constructMouse() { Mouse mouse = new Mouse("A","Wireless mouse"); computer.setMouse(mouse); } @Override public void constructScreen() { Screen screen = new Screen("A","Liquid crystal display"); computer.setScreen(screen); } @Override public void constructKeyboard() { Keyboard keyboard = new Keyboard("A","Ordinary keyboard"); computer.setKeyboard(keyboard); } @Override public Computer getResult() { return computer; } }
Advanced configuration implementation:
public class SupperComputerBuilder implements ComputerBuilder { private Computer computer = new Computer(); @Override public void constructLaptop() { Laptop laptop = new Laptop("S", "Mac Boor Pro"); computer.setLaptop(laptop); } @Override public void constructMouse() { Mouse mouse = new Mouse("A", "Wireless mouse"); computer.setMouse(mouse); } @Override public void constructScreen() { Screen screen = new Screen("S", "LCD curved screen"); computer.setScreen(screen); } @Override public void constructKeyboard() { Keyboard keyboard = new Keyboard("S", "Mechanical keyboard"); computer.setKeyboard(keyboard); } @Override public Computer getResult() { return computer; } }
In this specific builder, the configuration information of each component is set. It is simplified here. Each component has only type and name. In practice, each component object may contain different data items.
Commander: call the method in the builder to complete the creation of complex objects.
public class Director { private ComputerBuilder builder; public Director(ComputerBuilder builder) { this.builder = builder; } //Product construction and assembly method public Computer construct() { builder.constructLaptop(); builder.constructMouse(); builder.constructScreen(); builder.constructKeyboard(); return builder.getResult(); } }
The commander encapsulated the whole production process and isolated the client. The client only needs to obtain the final product without caring about the assembly process.
Client call example:
public class Client { public static void main(String[] args) { // General configuration computer assembly ComputerBuilder builder = new CommonComputerBuilder(); Director director = new Director(builder); Computer product = director.construct(); product.show(); System.out.println("------------------"); // Advanced configuration computer assembly builder = new SupperComputerBuilder(); director = new Director(builder); product = director.construct(); product.show(); // It can be implemented in the construction of other configurations } }
Execute the program and print the results as follows:
Notebook configuration: Huawei notebook Mouse configuration: wireless mouse Display configuration: LCD Keyboard configuration: normal keyboard ------------------ Notebook configuration: Mac Boor Pro Mouse configuration: wireless mouse Display configuration: LCD curved screen Keyboard configuration: mechanical keyboard
According to the above examples, we can find that if other configured computers are needed, we only need to create another Builder implementation class, and the assembly sequence of the guidance class can also be adjusted. In this case, the original function will not be affected, which is in line with the opening and closing principle in the design mode.
Application scenario
Applicable scenarios are actually the most important to understand design patterns. Only when you know what scenarios are applicable can you accurately use design patterns.
It can be seen from the above examples that the Builder pattern creates complex objects, which is suitable for scenes where the specific parts of the product often change, but the algorithm for combining them is relatively stable.
The builder mode is applicable to the following scenarios:
- The created object is complex and consists of multiple components. Each component is facing complex changes, but the construction sequence between components is stable and the results are different.
- The product class is very complex, or different call sequences in the product class have different effects;
- Various forms of products that need to be created have similar manufacturing processes and only differences in details;
- Using the generator to construct composite tree or other complex objects, the builder pattern can construct products step by step and delay;
- There are N optional parameters in the constructor, and various instances of new are troublesome. The constructor needs to be overloaded many times, and many parameters have default values.
Advantages and disadvantages
Through the above introduction, we can probably understand the advantages and disadvantages of the builder model.
advantage:
- Each specific builder is independent of each other, which can easily replace or add new specific builders, which is conducive to the expansion of the system.
- The encapsulation is good, and the construction and presentation are separated. The client does not need to know the details of the internal composition of the product, which is convenient to control the detail risk.
- The product creation process can be controlled more finely, and the builder can gradually refine the creation process without any impact on other modules.
Disadvantages of builder mode:
- Additional Builder interfaces and implementation classes need to be created;
- If the internal changes of the product are complex, it may lead to the need to define many specific builder classes to realize this change, resulting in the system becoming very large;
- If the product changes internally, the builder should also modify it synchronously, and the later maintenance cost is large.
- The products created by the builder mode generally have more in common and their components are similar. If there are great differences between products, the builder mode is not suitable for use, so its scope of use is limited to a certain extent;
The Builder mode can be changed as needed in the application process. If there is only one product type and only one specific Builder is required, the abstract Builder or even the conductor role can be omitted.
Factory mode VS builder mode
The concerns of builder mode and factory mode are different: Builder mode pays attention to the assembly process of parts, while factory method mode pays more attention to the creation process of parts, and the two can be used in combination.
Difference between builder mode and factory mode:
(1) The builder mode pays more attention to the calling sequence of methods, and the factory mode pays more attention to the creation of objects;
(2) The intensity of creating objects is different. The builder mode creates complex objects, which are composed of various complex components. The objects created by the factory mode are the same;
(3) The focus is different. The factory mode only needs to create the object, while the builder mode not only needs to create the object, but also needs to know what components the object is composed of;
(4) The builder mode is different according to the order in the construction process, and the final object component composition is also different.
Application of builder in JDK
The most direct application of builder mode is found in our most commonly used StringBuilder class. Take a look at the core code:
public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; } @Override public StringBuilder append(char c) { super.append(c); return this; }
For the implementation of StringBuilder's specific interface inheritance and other functions, you can refer to the above description to see the source code implementation.
Summary
This article takes you to practice the builder model, and introduces its composition and functions of each part in detail. The most important thing about design patterns is to understand their application scenarios, use appropriate design patterns in appropriate scenarios, and flexibly adapt according to specific environments.
New horizon of programOfficial account " "New horizons of programs", a platform that allows you to synchronously improve your soft power and hard technology, and provides a large amount of data