Java 这是DTO中生成器模式的正确用法吗?

Java 这是DTO中生成器模式的正确用法吗?,java,spring,design-patterns,Java,Spring,Design Patterns,假设我的PostDTO包含以下字段: private Long id; private ShortInfoUserDTO author; private CategoryDTO category; 我在它里面有CategoryTo,也有Builder,还有字段: private Long id; private String name; ShortInfoUserDTO有一些字段(不管是什么字段,但它也有Builder) 我的生成器模式如下所示(CategoryTo和 public stat

假设我的PostDTO包含以下字段:

private Long id;
private ShortInfoUserDTO author;
private CategoryDTO category;
我在它里面有CategoryTo,也有Builder,还有字段:

private Long id;
private String name;
ShortInfoUserDTO有一些字段(不管是什么字段,但它也有Builder)

我的生成器模式如下所示(CategoryTo和

public static Builder builder() {
    return new PostDTO.Builder();
}
public static class Builder {
    PostDTO instance = new PostDTO();        

    public Builder id(Long id) {
        instance.id = id;
        return this;
    }

    public Builder author(User user) {
        ShortInfoUserDTO author = ShortInfoUserDTO.builder()
                                                  .id(user.getId())
                                            .username(user.getUsername())
                                            .build();
        instance.author = author;
        return this;
    }



    public Builder category(Category category) {
          CategoryDTO categoryDto = CategoryDTO
                                      .builder()
                                      .id(category.getId())
                                      .name(category.getName())
                                      .build();           

          instance.category = categoryDto;            
          return this;
    }

    public PostDTO build() {
        return instance;
    }
}

一般来说,用这种方式构建author()和category()的想法好吗?像这样的架构合适吗?我问的原因之一是因为我有点担心NullPointerException

是的,只要你能接受这么多的样板代码,这是构建POJO的一种非常好的方式

可以帮助您减少样板文件的数量

另一种方法是使用映射工具而不是手动
DTO
构造

使用mapper,您可以执行以下操作:

public class So44937295ApplicationTests {
    final ModelMapper modelMapper = new ModelMapper();

    @Test
    public void manual() {
        final User user = new User();
        user.setId(42L);
        user.setUsername("John");
        user.setPassword("goof");

        final Category category = new Category();
        category.setId(23L);
        category.setName("Category 1");

        final PostDTO postDTO = new PostDTO();
        postDTO.setAuthor(modelMapper.map(user, ShortInfoUserDTO.class));
        postDTO.setCategory(modelMapper.map(category, CategoryDTO.class));

        assertEquals(user.getId(), postDTO.getAuthor().getId());
        assertEquals(user.getUsername(), postDTO.getAuthor().getUsername());

        assertEquals(category.getId(), postDTO.getCategory().getId());
        assertEquals(category.getName(), postDTO.getCategory().getName());
    }

    @Test
    public void auto() {
        final User user = new User();
        user.setId(42L);
        user.setUsername("John");
        user.setPassword("goof");

        final Category category = new Category();
        category.setId(23L);
        category.setName("Category 1");

        class Post {
            private User author;
            private Category category;
            // getters and setters
        }

        final Post post = new Post();
        post.setAuthor(user);
        post.setCategory(category);
        final PostDTO postDTO = modelMapper.map(post, PostDTO.class);

        assertEquals(post.getAuthor().getId(), postDTO.getAuthor().getId());
        assertEquals(post.getAuthor().getUsername(), postDTO.getAuthor().getUsername());

        assertEquals(post.getCategory().getId(), postDTO.getCategory().getId());
        assertEquals(post.getCategory().getName(), postDTO.getCategory().getName());
    }

    public static class PostDTO {
        private Long id;
        private ShortInfoUserDTO author;
        private CategoryDTO category;
        // getters and setters
    }

    public static class User {
        private Long id;
        private String username;
        private String password;
        // getters and setters
    }

    public static class ShortInfoUserDTO {
        private Long id;
        private String username;
        // getters and setters
    }

    public static class Category {
        private Long id;
        private String name;
        // getters and setters
    }

    public static class CategoryDTO {
        private Long id;
        private String name;
        // getters and setters
    }

}
所有转换逻辑都将使用反射(基于字段名)为您完成。您可以配置该行为