Should i use builder pattern in DTO?

2020-06-03 06:51发布

问题:

This might be a pretty subjetive question, but i would to know some more opinions. I've built a Rest API service with Spring MVC, and i implemented the DTO-Domain-Entity pattern. I want to know what do you think about implementing the Builder pattern in DTOs, something like

public class UserResponseDTO
    extends AbstractResponseDTO {

    private String username;
    private Boolean enabled;

    public UserResponseDTO(String username, Boolean enabled) {
        this.username = username;
        this.enabled = enabled;
    }

    public String getUsername() {
        return this.username;
    }

    public Boolean getEnabled() {
        return this.enabled;
    }

    public static class Builder {

        private String username;
        private Boolean enabled;

        public void setUsername(String username) {
            this.username = username;
        }

        public void setEnabled(Boolean enabled) {
            this.enabled = enabled;
        }

        public UserResponseDTO build(){
            return new UserResponseDTO(username, enabled);
        }
    }
}

According to the definition:

The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.

In most of my DTO cases (to not say all of them) i don't have a more complex object to build, such this case. And, honestly, i can't think of any example where construct a complex object if we are talking about DTOs.

One of the patterns which helps make immutable objects easier to use and to add clarity to code is the Builder pattern.

Builder pattern provides objects immutabiltiy. Then, we can think than a DTOs is the service response itself and should not be altered as this is a response (at least that is how i am thinking about it)


So what do you think? Should i use this pattern to DTOs (given the fact that this case, and probably most of them, does not satisfy the complex object principle)?

回答1:

My short answer is that it's a matter of preference. If you like the way that Builder Pattern works, apply it. For such a small case, I don't think it matters either way. My personal preference would be not to use Builder here as it doesn't seem to add much value.

My longer answer is that Builder Pattern is designed to facilitate easier configuration of complex objects without resorting to anti-patterns like telescoping constructor. In this case, you don't have an anti-pattern in either case; both options are relatively small and efficient.

While we're talking about preferences, though, I prefer a modified version of the builder pattern that uses a fluent interface; each method returns the instance of Builder so that the method calls can be chained together (rather than on separate lines). This is similar to the Java example in the article that you linked.

I'd modify your builder to look like this:

public static class Builder {

        private String username;
        private Boolean enabled;

        public Builder setUsername(String username) {
            this.username = username;
            return this; 
        }

        public Builder setEnabled(Boolean enabled) {
            this.enabled = enabled;
            return this;
        }

        public UserResponseDTO build(){
            return new UserResponseDTO(username, enabled);
        }
    }

Thus, using the builder would look something like this:

UserResponseDTO ur = new Builder().setUsername("user").setEnabled(true).build();

Again, just a matter of personal preference.