从域对象构建DTO的设计

时间:2014-02-11 10:11:24

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

我有一个域对象图,我需要构建一个DTO来将其发送到视图。如何正确设计?我看到两个选项,我可以在哪里放置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?

4 个答案:

答案 0 :(得分:3)

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

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

因此,为了将数据提供给您的视图,我建议使用简单的查询图层。通常,您需要一些非规范化数据来提高查询性能,并且无论如何都不会出现在您的域中。如果确实需要DTO,请直接从数据源映射它们。如果你能够获得更通用的数据容器结构,那么这就是一等奖。

答案 1 :(得分:2)

变体:

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

答案 2 :(得分:0)

  

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

     

2)...域对象将快速增长...

正如您所看到的,问题是两种替代方案都将您的模型与您的DTO耦合,因此您需要将它们分离:在它们之间引入一个负责执行映射/转换的层。

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

答案 3 :(得分:0)

  

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

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

此外,由于您希望发布到包含特定数据的View a DTO,我无法看到这些数据如何在域对象中保持 private 。你必须以某种方式揭露它。

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