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

jsc*_*man 7 java design-patterns data-transfer-objects dto builder-pattern

这可能是一个非常主观的问题,但我想知道一些更多的意见.我用Spring MVC构建了一个Rest API服务,并实现了DTO-Domain-Entity模式.我想知道你对在DTO中实现Builder模式有什么看法,比如说

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

根据定义:

Builder设计模式的目的是将复杂对象的构造与其表示分开.通过这样做,相同的构造过程可以创建不同的表示.

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

其中一种模式有助于使不可变对象更易于使用,并增加代码的清晰度,这是Builder模式.

Builder模式为对象提供了不可变性.然后,我们可以认为DTO是服务响应本身,不应该改变,因为这是一个响应(至少我正在考虑它)


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

Bob*_*ues 14

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

我更长的答案是,Builder Pattern旨在简化复杂对象的配置,而不需要使用像telescoping构造函数这样的反模式.在这种情况下,在任何一种情况下都没有反模式; 两种选择都相对较小且有效.

虽然我们在谈论偏好,但我更喜欢使用流畅界面的修改版本的构建器模式; 每个方法返回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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

UserResponseDTO ur = new Builder().setUsername("user").setEnabled(true).build();
Run Code Online (Sandbox Code Playgroud)

再次,只是个人偏好的问题.