This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.


Hello, everyone, I am a ~

Before the “vernacular design mode” because of the work was shelved, now set sail again, and with the framework source code analysis together to eat, the theory and practice perfect combination.

Students who are not familiar with design patterns can first read “23 Kinds of Design patterns in one Sentence popular Interpretation” to have a comprehensive understanding of design patterns, form an overall framework, and then break down one by one.

After the release of the prototype mode of the last period, I received the thanks of the fans, and a creative motivation is more sufficient.

Today we’re going to take a look at the Builder pattern, which is also the creative design pattern.

define

The official definition of

Separating the construction of a complex object from its representation allows the same construction process to create different representations.

Easy to interpret

Provide a way to create objects that are complex in detail and must be exposed to the consumer. Mask the process, not the details.

Similar to building a house, we only need to give the materials and design drawings to the workers to build the house we want. We don’t pay attention to the process of building the house, but we can design the details by ourselves.

chart

Code demo

Source code: Builder mode extraction code: VPQT

The directory structure

It is recommended that anyone learning design patterns build a Maven project and install Lombok dependencies and plug-ins.

And set up the following package directory for easy induction and arrangement.

Pom as follows

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.10</version>
    </dependency>

Copy the code

Development scenarios

Now there’s a phone builder, and I’m going to get it to make phones for me without branding or configuration. How do you do that?

Code demo

1. Create a mobile phone class

@Data
public class Phone {       
        / / processor
        protected String cpu;
        / / memory
        protected String mem;
        / / disk
        protected String disk;
        // Screen size
        protected String size;
}
Copy the code

2. Create the Builder interface

// Define the builder's template method
public interface Builder {
    Phone phone = new Phone();
    void buildCpu(String cpu);
    void buildMem(String mem);
    void buildDisk(String disk);
    void buildSize(String size);

    default Phone getPhone(a){
        returnphone; }}Copy the code

3. Create aVivoThe builder of mobile phones

public class VivoPhoneBuilder implements Builder{
		// Implementation of builder details
    @Override
    public void buildCpu(String cpu) {
        phone.cpu=cpu;
    }

    @Override
    public void buildMem(String mem) {
        phone.mem=mem;
    }

    @Override
    public void buildDisk(String disk) {
        phone.disk=disk;
    }

    @Override
    public void buildSize(String size) { phone.size=size; }}Copy the code

4. Create a test class

public class MainTest {
    public static void main(String[] args) {
        VivoPhoneBuilder builder = new VivoPhoneBuilder();
        builder.buildCpu("888");
        builder.buildDisk("512");
        builder.buildMem("16");
        builder.buildSize("plus"); Phone phone = builder.getPhone(); System.out.println(phone); }}Copy the code

5. Output the result

If I need to produce OPPO phones at this time, I just need to create an OppoPhoneBuilder to implement the Builder interface.

Chain calls

I believe you have encountered such code in development, like a chain can always be called.

So how do you implement the chain builder?

There are two ways:

1. Change the return value toBuilder

public interface Builder {
    Phone phone = new Phone();
    // change the implementation class to Builder
    Builder buildCpu(String cpu);
    Builder buildMem(String mem);
    Builder buildDisk(String disk);
    Builder buildSize(String size);

    default Phone getPhone(a){
        returnphone; }}Copy the code

Test 1

public class MainTest {
    public static void main(String[] args) {
        / /...

        VivoPhoneBuilder builder2 = new VivoPhoneBuilder();
        Phone phone1 = builder2
                .buildCpu("888")
                .buildDisk("512")
                .buildMem("16")
                .buildSize("plus")
                .getPhone();
        System.out.println("phone1:"+phone1); }}Copy the code

Results 1

2. Uselombok

@Data
@Builder   // Use the chain builder
@NoArgsConstructor
@AllArgsConstructor
public class Phone {
   / /...
} 
Copy the code

Test 2

public class MainTest {
    public static void main(String[] args) {
      
				/ /...
      
        Phone build = Phone.builder()
                .cpu("888")
                .mem("16")
                .disk("512")
                .size("plus").build();
        System.out.println("builder:"+build); }}Copy the code

The results of 2

Application scenarios

  • The StringBuilder:append();Who append?
    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;
    }
Copy the code
  • Swagger-ApiBuilder;
  • Quick implementation:Lombok-@Builder

conclusion

The Builder pattern provides different representations of the same build process, producing objects like a pipeline. For new objects, you only need to create the corresponding builder, without modifying the source code.

Lombok provides us with a quick implementation of the Builder pattern (@Builder) to be applied to actual coding.