【问题标题】:design of building DTO from domain object从领域对象构建 DTO 的设计
【发布时间】:2014-03-09 01:26:35
【问题描述】:

我有一个域对象图,我需要构建一个 DTO 将其发送到视图。如何正确设计?我看到 2 个选项可以将 DTO 构建代码放在哪里:

1) 进入 DTO 构造函数。但是域对象必须通过 getter 将所有字段呈现给 DTO,因此它不是 DDD。

public DTO(DomainObject domain) {
   /// access internal fields of different domain object.
}

2) 进入域对象。访问字段不会有问题,但添加新视图时域对象会增长得非常快。

public DTO1 createDTO1() {
    ...
}

public DTO2 createDTO1() {
    ...
}

// and so on...

我应该如何正确构建 DTO?

【问题讨论】:

    标签: java design-patterns domain-driven-design dto


    【解决方案1】:

    变体:

    1. DTO 中具有简单类型的构造函数:public DTO(Long id, String title, int year, double price)
    2. 单独的类 - 转换器,方法如下:DTO1 createDTO1(DomainObject domain)
    3. 用于将属性从一个对象复制到另一个对象的框架,例如 Dozer:http://dozer.sourceforge.net/

    【讨论】:

    • ad 2. 转换器仍然需要访问域对象的私有字段,对吧?
    • 自定义转换器通常无权访问私有字段。可以使用 1. 中的构造函数或 DTO 设置器。
    【解决方案2】:

    1) ... 域对象必须通过 getter 将所有字段呈现给 DTO ...

    2) ...领域对象会增长得非常快...

    如您所见,问题在于这两种选择都将您的模型与 DTO 耦合,因此您需要将它们解耦:在它们之间引入一个层来负责执行映射/转换。

    您可能会发现this SO question 很有用。

    【讨论】:

      【解决方案3】:

      域对象必须通过 getter 将所有字段呈现给 DTO,所以它不是 一个DDD

      仅仅因为域对象具有 getter 并不会使其贫血或反 DDD。您可以有 getter 行为。

      此外,由于您想发布到查看包含特定数据的 DTO,我无法看到这些数据如何在域对象中保持私有。你必须以某种方式暴露它。

      解决方案 2) 打破了关注点和分层的分离(创建 DTO 不是域对象的业务),所以我会坚持使用 1) 或@pasha701 的替代方案之一。

      【讨论】:

        【解决方案4】:

        我认为这里有一个更大的问题。您应该查询您的域。您的域应该关注行为,因此很可能不包含适合视图格式的数据,尤其是用于显示目的。

        如果您将整个Customer 对象发送回Edit,那么您正在执行非常关注数据的基于实体的交互。您可能想尝试更多地关注基于任务的交互。

        因此,为了让数据显示在您的视图中,我建议使用一个简单的查询层。很多时候,您需要一些非规范化数据来提高查询性能,而且这些数据无论如何都不会出现在您的域中。如果您确实需要 DTO,则直接从您的数据源映射它们。如果您可以使用更通用的数据容器结构,那将是一等奖。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-05-26
          • 2023-04-02
          • 2015-01-06
          • 1970-01-01
          • 1970-01-01
          • 2011-04-03
          • 1970-01-01
          相关资源
          最近更新 更多