Create and destroy objects - consider using constructors when multiple constructor parameters are encountered

Posted by daveh33 on Sun, 26 Dec 2021 10:53:02 +0100

preface

In the previous section, we discussed the advantages and disadvantages of using static factory method instead of constructor. In this section, we discussed how to deal with multiple constructor parameters. Static factories and constructors have a common limitation. Neither of them can be well extended to a large number of optional parameters.

An inelegant method

Use overlapping constructor mode

For this class with multiple optional parameters, some people will use the overlapping constructor pattern. First provide a constructor with only necessary parameters, the second constructor has one optional parameter, the third has two, and so on. The problem is that too many constructor parameters make it difficult to write and read client code. Although IDEA can help us prompt the corresponding attribute names and parameters, it is too eye-consuming and easy to make mistakes. For example, we reversed the position of two parameters of the same type. Although the compiler will not report an error, there has actually been a problem.

Using JavaBeans pattern

That is, first call the no parameter constructor to create the object, then call the setter method to set every necessary parameter, and each relevant optional parameter. This is also the method I often use. To be honest, I don't think it's a problem. How else to deal with the problem of filling data. However, there are still some problems mentioned in the book, such as sudden error reporting in the middle, resulting in inconsistent object creation with our assumptions.

Elegant approach

Building objects using Builder

public class Article {
    private Integer articleId;
    private String title;
    private Integer categoryId;
    public static class Builder {
        private String title;
        private Integer categoryId;
        private Integer articleId = Integer.valueOf(0);
        public Builder(String title, Integer categoryId) {
            this.title = title;
            this.categoryId = categoryId;
        }
        public Builder articleId(Integer articleId) {
            this.articleId = articleId;
            return this;
        }
        public Article build(){
            return new Article(this);
        }
    }
    private Article(Builder builder) {
        this.articleId = builder.articleId;
        this.title = builder.title;
        this.categoryId = builder.categoryId;
    }
}

Article article =new Article.Builder("Create and destroy objects-Consider using a constructor when multiple constructor parameters are encountered",15)
                .articleId(0).build();

Although it is easy to read, it is still a bit troublesome to write the Builder. We can directly generate the corresponding Builder method with Lombok's @ Builder annotation.

@Builder(toBuilder = true)
@Getter
public class Author {
    @Builder.Default
    private String userName = "Temporary camp";
    private String company;
    private Integer age;
    @Singular("addArticle")
    private List<Article> articleList;
}
List<Article> articleList =new ArrayList<>();
        articleList.add(article);
        Author author = Author.builder().userName("Temporary camp")
        .articleList(articleList)
        .addArticle(article).build();
        author.getArticleList();

@Builder declares an entity, which means that it can be initialized in builder mode. The @ getter annotation means that only getters are exposed and setter s of all properties are closed, that is, private modification

To set default values for properties, use @ builder Default annotation,

For the List in the entity class, you can add @ single annotation. Note the following addArticle, which means that we can use this method to put a single entity in it

Both articleList(articleList) and addArticle(article) can be used

It should be noted that the calling methods generated by Lombok are different from those written by ourselves.

The Builder method is provided for the creation of objects. It provides that the private setter is maintained externally when designing data entities, and the Builder method is adopted for the assignment of attributes. This method is the most elegant and more in line with the principle of encapsulation. It does not disclose the write operation of attributes!

The builder mode can constrain its parameters. The build method can verify these constraints. After copying the parameters from the builder to the object, it can verify them in the object domain instead of the builder domain. If any constraints are violated, the build method should throw IllegalStateException. The builder pattern is very flexible, and you can use a single builder to build multiple objects. The only disadvantage is that in order to create an object, an intermediate object must be created first, and the builder mode also makes the construction process more lengthy.

summary

If there are multiple optional parameters in the class, the Builder mode is a good choice when designing this kind. At the same time, it is more readable than the original method.


Author: temporary camp
Link: https://juejin.cn/post/6995084423876050981
Source: Nuggets
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, and for non-commercial reprint, please indicate the source.

Topics: Java