[Design Pattern Practice Notes] Section 3: Builder Pattern

builder mode

Separating a complex build from its representation allows the same build process to create different representations.

Most design patterns do not only exist in the IT world, there are often quite a few examples in real life, and the builder pattern is no exception. The original meaning of builder is the builder, and it is usually used in the field of construction, ranging from tile-roofed single rooms to 100-meter-high buildings. These buildings have some fixed components, such as walls, roofs, doors and windows. Builders build a house by adding materials step by step according to the composition of the house.

Generally speaking, we use the builder pattern in the code, because some classes have fixed components, and we do not want to expose the creation process of too many instances, so as to reduce the complexity of system maintenance. The created instance is also called a representation .

Use builder to create interface generic return value

Let's first look at the return code of an interface:

public class LoginController {

    // Log in
    public Result<String> login(String username, String password) {
        Result<String> result = new Result<>();
        if ("javanote".equalsIgnoreCase(username) && "123456".equalsIgnoreCase(password)) {
            result.setCode(0);
            result.setData("login successful");
        } else {
            result.setCode(1);
            result.setData("Login failed");
        }
        return result;
    }
}

public class Result<T> {
    private int code;
    private T data;

    // ...omit getter s and setter s
}

Generally, our interfaces are return values ​​in a fixed format, and it will work to directly new a return instance, but we have a better way to achieve it, that is, use the builder pattern to create a return instance.

So how can we use the builder pattern to optimize our code?

According to the concept of the builder pattern, at least two roles are required: the presenter and the builder. Representation is the object we need to create.

public class ResultBuilder<T> {
    private Result<T> result;

  	// Provide builder instance via static method
    public static <T> ResultBuilder<T> builder() {
        return new ResultBuilder<>();
    }

  	// Private constructor, to ensure that the builder instance can only be provided through its own open methods
    private ResultBuilder() {
        this.result = new Result<>();
    }

    public ResultBuilder code(int code) {
        this.result.setCode(code);
        return this;
    }

    public ResultBuilder data(T data) {
        this.result.setData(data);
        return this;
    }

    public Result<T> build() {
        return this.result;
    }
}

First of all, we provide a ResultBuilder as a builder. There are many ways to implement it here. The core idea is to delegate the whole process of construction to the builder role. Here, static methods are used to simplify the operation.

In this way, the optimized client code is as follows:

public class LoginController {

    public Result<String> login(String username, String password) {
        if ("javanote".equalsIgnoreCase(username) && "123456".equalsIgnoreCase(password)) {
            return ResultBuilder.<String>builder()
                    .code(0)
                    .data("login successful")
                    .build();
        }
        return ResultBuilder.<String>builder()
                .code(1)
                .data("Login failed")
                .build();
    }
}

summary

The builder pattern is a very simple design pattern, and it is also very commonly used, especially when encountering a class with many parameters to create an instance, it can greatly simplify the situation of human new. The creational design pattern is originally designed to serve the creation of objects. If it is eaten with the factory pattern, it tastes better.

In actual programming, adding a builder class may make the system more complex as a whole, but don't worry. There are many assistive development tools to help us reduce the pressure in practice, such as the @Builder annotation provided in the Lombok plug-in to create a builder for a class, and how to use it can be explored in practice!

Practise true knowledge, let's work together!

Follow the official account of "Java Practice Notes" to get all the source code!

Copyright statement: This article is an original article of the public account "Java Practice Notes". Please contact the author for reprinting, and attach a link to the original source and this statement.
Original link: https://mp.weixin.qq.com/s/33YfZdDnIFJfDw5wDaa0bA

Tags: Java Design Pattern

Posted by smoked1 on Thu, 08 Sep 2022 01:31:58 +0930