我有一个域对象图,我需要构建一个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?
答案 0 :(得分:3)
我认为这里有一个更大的问题。您应该不查询您的域名。您的域应该专注于行为,因此很可能不会以适合视图的格式包含数据,尤其是出于显示目的。
如果您将整个(例如)Customer
对象发送回Edit
,那么您正在执行非常注重数据的基于实体的互动。您可能希望尝试更多地关注基于任务的交互。
因此,为了将数据提供给您的视图,我建议使用简单的查询图层。通常,您需要一些非规范化数据来提高查询性能,并且无论如何都不会出现在您的域中。如果确实需要DTO,请直接从数据源映射它们。如果你能够获得更通用的数据容器结构,那么这就是一等奖。
答案 1 :(得分:2)
变体:
答案 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的替代方案之一。