Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities

preface

A design pattern is a set of repeated, familiar, catalogued code design lessons. It describes some recurring problems in the software design process, and the solutions to this problem. That is to say, it is a series of routines to solve a specific problem. It is a summary of the code design experience of predecessors. It has a certain universality and can be used repeatedly. The goal is to improve code reusability, code readability, and code reliability.

It is a summary of the most valuable lessons learned in object-oriented design. Before speaking may be relatively familiar with some of the design pattern, but carefully pondering or some questions, just at present relatively have more spare time, you can re-learn the design pattern!

This article is about the Builder pattern. Includes the design, implementation, and questions of the Builder pattern.

define

The Builder pattern is a design pattern that separates the construction of a complex object from its representation so that the same construction process can create different representations. — Baidu Encyclopedia

When you create an object of a class, you get it directly using its constructor. For complex products, however, there may be many and complex attributes. In the code to use this product object to create directly you need to understand all the attributes of this class and its operation process, in order to normally create their own want.

For the builder pattern, the creation of the product object is delegated to a guy called the builder, and the client code is retrieved from the builder, which is the separation of build and presentation in the definition.

For a complex product, there are many things that the client code does not need to know, and some things that the client code needs to specify. The builder builds the contents of this object either by default or by passing arguments through client code.

Traditional builder

Here is an example of gaigong Pot:

In this case, the customer code needs the product object, which is the chicken pot, and the customer code ultimately obtains this product object through the supervisor. The client code knows that it needs the product and it knows something about it, that it’s specified by the client code, but there are a lot of attributes or components of the product that the client code doesn’t want to learn and that are all built by the builder.

Finally, our client code uses the director’s Construct () method to specify parts of the product to get the desired product object.

Code diagram:

/ / product
class ChickenPot{
    private Qz qz;
    private Dyc dyc;
    private Td td;
    private Jzg jzg;
    / /...
    // getter setter
}
Copy the code
// Abstract builder (interface or abstract class)
interface AbstractBuilder{
    // Specify the parts
    void qz(Qz qz);
    void dyc(Dyc dyc);
    void td(Td td);
    void jzg(Jzg jzg);
    / /...
    // Assemble the finished product
    ChickenPot build(a);
}
Copy the code
// Concrete builder
class Builder implements AbstractBuilder{
    private Qz qz;
    private Dyc dyc;
    private Td td;
    private Jzg jzg;
    / /...
    // We can also replace void with this to facilitate chain calls
    void qz(Qz qz){
        this.qz = qz;
    }
    void dyc(Dyc dyc){
        this.dyc = dyc;
    }
    void td(Td td){
        this.td = td;
    }
    void jzg(Jzg jzg){
        this.jzg = jzg;
    }
    ChickenPot build(a){
        ChickenPot chicken = new ChickenPot();
        chicken.setQz(this.qz);
        chicken.setDyc(this.dyc);
        chicken.setTd(this.td);
        chicken.setJzg(this.jzg);
        returnchicken; }}Copy the code
class Director{
    private AbstractBuilder builder;
    Director(AbstrctBuilder builder){
        this.builder = builder;
    }
    public ChikenPot construct(Qz qz,Dyc dyc,Td td,Jzg jzg){
        builder.qz(qz);
        builder.dyc(dyc);
        builder.td(td);
        builder.jzg(jzg);
        returnbuilder.build(); }}Copy the code

This is a simple implementation of the Builder pattern, either by masking the client code directly to the build order, or by specifying the full content complexity of the object.

In fact, the above code shows that the customer adds the four side dishes by himself, and assigns the attribute values of thousand pieces, bean sprouts and so on. In more cases, these are actually the default product specified by the builder. There are few fields that really let the client code pass in content.

Simplified version

The simplified version does away with the director and lets the client code fetch the production object directly using the builder’s methods.

In the actual situation, there may not be too complex interdependence of object attributes. For the product, it only needs to build the part that needs to specify the content to obtain the object according to its own needs, without involving the dependency order, so it can not use the commander link.

Builder Generator can also be installed on Idea to produce the Builder with one click.

The code is pretty much the same

The client code goes directly to the builder

ChickenPot chicken = new ChickenPotBuilder().withQz("xxx").withTd("xxx").build();
Copy the code

The problem

What’s the difference between builder and factory?

The biggest difference, in my opinion, is that one is passing in an abstract description factory to create an object of which concrete class of an abstract class? The other is to pass something to create a concrete class what kind of object?

The factory mode client code requires less knowledge of the product than the builder mode. The client code just needs what it uses. The builder returns a concrete class object.

The builder type of client code is relatively knowledgeable about the product it is working with, but does not need to fully understand the rationale. A concrete class can produce a wide variety of objects, and the client code guides part of that, leaving it up to the builder to build the object.

Factory mode:

Builder mode:

Why doesn’t the client code just use the constructor or Setter for the production class?

Simple objects do not matter, of course. Using constructors for complex concrete classes either permutations and combinations of constructors, or for all parameters, increases knowledge of production classes. The second is attribute dependence. For an attribute content, it needs to rely on other attributes of the current product object when it is used, so we cannot understand the operation details of the product and create the correct object. Initialization is done by the builder and further modifications are made to your content before it is assembled into the production object.

conclusion

The Builder pattern is a new way to provide client code with access to complex type objects, encapsulated over native creation, but also providing the client code with options for each step. By extracting abstractions, the builder can also be easily extended, and different builders can specify different details of hidden operations and customer-passed content, providing more options for composite properties within the product object.