Understand the Builder pattern?

The Builder pattern definition: Separates the construction of a complex object from its representation so that the same construction process can create different representations.

Two important things to take away from this concept are that the build and presentation are separate, and that different instance objects can be obtained through the same build process.

Roles in Builder mode:

  • Product Category: specific and complete products.

  • Builder abstract: The specification of the components of a product, typically by subclass implementation of the concrete building process.

  • ConcreteBuilder: Implements all methods defined by an abstract class and returns a constructed object.

  • Director: Unify the build process, arrange the order of existing modules, and then tell Builder to start building.

When should you consider using the Builder pattern?

From the definition of the Builder pattern, you can see that the builder pattern deals with the process of building objects, which in Java involves constructors and parameters.

If an object is constructed with more than four optional parameters, then the builder pattern can be used to optimize the process of building the object.

Normal build process

Now we need a computer object that contains the motherboard, memory, CPU, monitor, and keyboard. The motherboard, memory and CPU are required, while the monitor and keyboard are optional.

public class Computer {
    private String mBoard;
    private String cpu;
    private String ram;
    private String Display;
    private String keyboard;

    public Computer(String mBoard, String cpu, String ram) {
        this.mBoard = mBoard;
        this.cpu = cpu;
        this.ram = ram;
    }

    public void setDisplay(String display) {
        Display = display;
    }

    public void setKeyboard(String keyboard) {
        this.keyboard = keyboard;
    }

    @Override
    public String toString(a) {
        return "Computer{" +
                "mBoard='" + mBoard + '\' ' +
                ", cpu='" + cpu + '\' ' +
                ", ram='" + ram + '\' ' +
                ", Display='" + Display + '\' ' +
                ", keyboard='" + keyboard + '\' ' +
                '} ';
    }

    public static void main(String[] args) {
        Computer hwComp = new Computer("Asus z - 01".intel-i7."Pirate Ship D01");
        hwComp.setDisplay(Huawei Display);
        hwComp.setKeyboard("Huawei Keyboard");
        System.out.println(hwComp.toString());
        / / Computer {mBoard = 'asus z - 01' = 'Intel - i7 CPU, ram =' pirate ship D01,
        //Display=' huawei Display ', keyboard=' Huawei keyboard '}

        Computer lenovoComp = new Computer("Msi z - 01"."AMD Dozer"."Samsung S02." ");
        lenovoComp.setDisplay("Lenovo Display");
        lenovoComp.setKeyboard("Lenovo Keyboard");
        System.out.println(lenovoComp.toString());
        //Computer{mBoard=' z-01', CPU ='AMD dozer ',
        //ram=' S02', Display=' S02', keyboard=' S02'}}}Copy the code

With a normal build process, the caller needs to know what parameters and meanings are filled in during the build process, and the optional parameters are set themselves. If less parameters, can also accept, if the actual development, some object need to initialize parameters have 7, 8, and if that’s what I put, the structure of the object process is not controlled, depends entirely on the developer, may be in the running process, object missing parameters result in incomplete, bugs. At this point the constructor pattern is used to solve the problem.

How to implement the Builder pattern?

  1. First, you need to define a product to be used and the parameters to be used by the product. The constructor specifies the parameters that must be defined for the product. The optional parameters provide the corresponding set method.
public   class Computer {
    private String mBoard;
    private String cpu;
    private String ram;
    private String Display;
    private String keyboard;
    public Computer(String mBoard,String cpu,String ram ) {
        this.mBoard = mBoard;
        this.cpu = cpu;
        this.ram = ram;
    }

    public void setDisplay(String display) {
        Display = display;
    }

    public void setKeyboard(String keyboard) {
        this.keyboard = keyboard;
    }

    @Override
    public String toString(a) {
        return "Computer{" +
                "mBoard='" + mBoard + '\' ' +
                ", cpu='" + cpu + '\' ' +
                ", ram='" + ram + '\' ' +
                ", Display='" + Display + '\' ' +
                ", keyboard='" + keyboard + '\' ' +
                '} '; }}Copy the code
  1. Define a Builder object that specifies the components of the product
public abstract class Builder {
    public abstract void buildKeyboard(a);
    public abstract void buildDisplay(a);
    public abstract Computer build(a);
}
Copy the code
  1. Then through the concrete Builder object, the concrete construction process is realized
public class HuaweiCompBuilder extends Builder {
    private Computer computer;

    public HuaweiCompBuilder(String mBoard, String cpu, String ram) {
        this.computer = new Computer(mBoard,cpu,ram);
    }

    @Override
    public void buildKeyboard(a) {
        computer.setKeyboard("Huawei Keyboard");
    }

    @Override
    public void buildDisplay(a) {
        computer.setDisplay(Huawei Display);
    }

    @Override
    public Computer build(a) {
        returncomputer; }}public class LenovoCompBuilder extends Builder{
    private Computer computer;

    public LenovoCompBuilder(String mBoard, String cpu, String ram) {
        this.computer = new Computer(mBoard,cpu,ram);
    }

    @Override
    public void buildKeyboard(a) {
        computer.setKeyboard("Lenovo Keyboard");
    }

    @Override
    public void buildDisplay(a) {
        computer.setDisplay("Lenovo Display");
    }

    @Override
    public Computer build(a) {
        returncomputer; }}Copy the code
  1. Finally, a Director object is provided to arrange the build order and unify the build process.
public class Director {
    public void construct(Builder builder){ builder.buildDisplay(); builder.buildKeyboard(); }}Copy the code
  1. Finally, the developer obtains the desired objects through concrete subclasses
        Builder builder = new HuaweiCompBuilder("Asus z - 01".intel-i7."Pirate Ship D01");
        Director pcDir = new Director();
        pcDir.construct(builder);
        Computer computer = builder.build();
        / / Computer {mBoard = 'asus z - 01' = 'Intel - i7 CPU, ram =' pirate ship D01,
        //Display=' huawei Display ', keyboard=' Huawei keyboard '}
        System.out.println(computer.toString());


        Builder lenovoCompBuilder = new LenovoCompBuilder("Msi z - 01"."AMD Dozer"."Samsung S02." ");
        Director lenDic = new Director();
        lenDic.construct(lenovoCompBuilder);
        Computer lenComputer = lenovoCompBuilder.build();
        //Computer{mBoard=' z-01', CPU ='AMD bulldozer ', ram=' Samsung S02',
        //Display=' keyboard ', keyboard=' keyboard '}
        System.out.println(lenComputer.toString());
Copy the code

The developer uses a concrete subclass of Builder, then implements the build process through the Director object, and finally obtains the built object through the Builder object. This is how the traditional builder pattern is implemented.

Simplify the implementation

In the traditional builder mode, the Director object is used to unify the construction process, but in fact, most of the time, the caller already knows how to build the desired object, so we can remove the Director role and simplify the builder mode

public class ComputerSim {
    private String mBoard;
    private String cpu;
    private String ram;
    private String display;
    private String keyboard;

    public ComputerSim(Builder builder) {
        this.mBoard = builder.mBoard;
        this.cpu = builder.cpu;
        this.ram = builder.ram;
        this.display = builder.display;
        this.keyboard = builder.keyboard;
    }
    public static class Builder {
        private String mBoard;
        private String cpu;
        private String ram;
        private String display;
        private String keyboard;
        public Builder(String mBoard,String cpu,String ram){
            this.mBoard = mBoard;
            this.cpu = cpu;
            this.ram = ram;
        }
        public Builder setDisplay(a) {
            this.display = Huawei Display;
            return this;
        }

        public Builder setKeyboard(a) {
            this.keyboard = "Huawei Keyboard";
            return this;
        }
        public ComputerSim build(a){
            return new ComputerSim(this); }}@Override
    public String toString(a) {
        return "ComputerSim{" +
                "mBoard='" + mBoard + '\' ' +
                ", cpu='" + cpu + '\' ' +
                ", ram='" + ram + '\' ' +
                ", display='" + display + '\' ' +
                ", keyboard='" + keyboard + '\' ' +
                '} ';
    }

    public static void main(String[] args) {
        ComputerSim computerSim = new ComputerSim.Builder("Asus z - 01".intel-i7."Pirate Ship D01").setDisplay().setKeyboard().build();
        //ComputerSim{mBoard=' Asus Z-01 ', CPU =' Intel-i7 ',
        // ram=' D01', display=' huawei display ', keyboard=' Huawei keyboard '}System.out.println(computerSim); }}Copy the code

The simplified version uses static inner classes to construct objects, and each step returns the constructed object to achieve chained references, simplifying the implementation process.

conclusion

The Builder pattern, which unifies the construction process of complex objects, is particularly obvious in providing uniform services. There are many application examples of the Builder pattern in Spring, Mybatis and other frameworks. It’s interesting to see how the Builder pattern is applied within these frameworks.

💖 see complete small event

If you find this article helpful or inspiring, I’d like you to move your little finger:

‘Like’ item: One item for more people (‘ Like ‘item: Never panic (乛◡乛)).

Pay attention to the public account [JAVA development], share the original knowledge from time to time.

Take a stroll through wechat and see if other articles inspire you.