我应该在 DTO 中使用构建器模式吗?

Should i use builder pattern in DTO?

这可能是一个相当主观的问题,但我想知道更多的意见。我用 Spring MVC 构建了一个 Rest API 服务,并且我实现了 DTO-Domain-Entity 模式。我想知道您如何看待在 DTO 中实现 Builder pattern,例如

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);
        }
    }
}

根据定义:

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.

在我的大多数 DTO 案例中(不是说所有案例),我没有要构建的更复杂的对象,例如这种情况。而且,老实说,如果我们谈论 DTO,我想不出任何构造复杂对象的例子。

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

构建器模式提供对象不变性。然后,我们可以认为 DTO 是服务响应本身,不应更改,因为这是响应(至少我是这么想的)


那你怎么看?我应该将这种模式用于 DTO(考虑到这种情况,可能大多数情况下,不满足复杂对象原则)?

我的简短回答是,这是一个偏好问题。如果您喜欢 Builder Pattern 的工作方式,请应用它。对于这么小的案例,我认为这两种方式都不重要。我个人的偏好是不在这里使用 Builder,因为它似乎没有增加太多价值。

我更长的回答是,Builder Pattern 旨在简化复杂对象的配置,而无需诉诸像伸缩构造函数这样的反模式。在这种情况下,您在任何一种情况下都没有反模式;这两个选项都相对较小且高效。

尽管我们在谈论首选项,但我更喜欢使用流畅界面的构建器模式的修改版本;每个方法 returns Builder 的实例,以便可以将方法调用链接在一起(而不是在单独的行上)。这类似于您链接的文章中的 Java 示例。

我会将您的构建器修改为如下所示:

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);
        }
    }

因此,使用构建器看起来像这样:

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

同样,这只是个人喜好问题。