DDD:Dto 汇编器是不是应该成为域层的一部分?
Posted
技术标签:
【中文标题】DDD:Dto 汇编器是不是应该成为域层的一部分?【英文标题】:DDD: Should a Dto Assembler be a part of Domain Layer?DDD:Dto 汇编器是否应该成为域层的一部分? 【发布时间】:2016-02-27 00:26:34 【问题描述】:提前致谢。
我在 Domain Layer 库中有一些 Aggregates。此外,一些 DTO 位于单独的库中,在 Server 和 Client 端之间共享。
一个实体的聚合比它的DTO提供更多的信息。因此,为了从 DTO 转换为 Aggregate,存储库 应该由 Dto 汇编程序 访问。 repositories 的接口在 Domain Layer 中。这就是为什么我得出结论 DtoAssembler 应该是 DomainLayer 的一部分。
是这样吗?
【问题讨论】:
感谢您的回答。我仍在尝试将它们放在一起。我稍微编辑了我的问题。我提到 DtoAssembler 规定了存储库应该有哪些方法。并且存储库的接口在 DL 中。这就是为什么我开始考虑将 DtoAssembler 作为 DL 的一部分...... 我的错误是我想使用 DtoAssembler 将 Dto 转换为 Aggregate。感谢答案,我知道最好在 Application Services 中进行转换和应用。 【参考方案1】:不,这在 DDD 的上下文中是完全错误的。
尝试询问(非技术)领域专家他对 DTO 汇编器的看法。他会用质疑的大眼睛看着你。
DTO(以及它们的汇编程序)是一个技术概念 - 它们在您系统的特定接口的上下文中定义数据结构。
存储库大多返回聚合。如果您在数据库中查询未在您的域中建模的统计数据,则存储库也可能返回不可变数据对象。只需确保在执行此操作时不会意外遗漏域概念即可。
一旦您从存储库中获得数据(无论是聚合还是数据对象),您就可以将其输入 DTO 组装器。
【讨论】:
谢谢! DtoAssembler 需要一个 IRepository 才能将 Dto 转换为 Aggregate,对吗? DtoAssembler 应该是“聪明的”,它不仅应该获取聚合,而且应该对其应用更改,我对吗? (这是因为可能会发生Dto中的数据与检索到的Aggregate的数据不同,而Id是相同的...)...? 我会保持 DtoAssembler 简单,并在应用程序服务中做所有重要的事情。这样,DtoAssembler 只需获取构造 DTO 所需的输入,在必要时应用转换(例如序列化),然后返回 DTO。 谢谢,我喜欢这个想法 :),那么反过来,从 Dto 到 Aggregate 的转换呢?我可能有一个误导性的想法,即 DtoAssembler 也应该能够从 Dto 转换为 Aggregate... 在大多数情况下,直接将 DTO 转换为聚合是没有意义的。您确定要使用 DDD 吗?这听起来很像您正在构建一个 CRUD 风格的应用程序。我建议您阅读有关 DDD 应用程序服务的内容。它们适用于您尝试在 DtoAssembler 中执行的操作。【参考方案2】:在我看来,不一定。由于您使用的是分层架构,我假设您的 DTO 位于上层——通常是 服务层——充当服务器和客户端之间的通信点。实际上,正如其名称所暗示的(数据传输对象),DTO 的主要目的是实现通信,在不附加任何逻辑的情况下传输信息 - 例如。操作。
层应该只知道位于下方的那些,而不是上方;因此,DTO 应该保存在服务层中,并由负责的人使用 - 例如,命令处理器 - 以便从存储库中检索域对象并执行涉及的任何操作。
底线:DTO 不适用于域,它们属于服务/通信。
【讨论】:
谢谢!您提供了命令处理器的示例。这让我认为转换 Dto->Aggregate 和 Aggregate->Dto 可以在 ServiceLayer 中完成,避免 DtoAssembler。你认为这会是比拥有一个“聪明”的 DtoAssembler 更好的方法吗,它不仅应该能够获取聚合,还应该对其进行更改? (可能会出现 Dto 中的数据与检索到的 Aggregate 的数据不同,而 Id 相同) DtoAssembler 应该尽可能地笨拙,通常它只会将字段从一个对象映射到另一个对象 - 例如,在您的聚合和您的 DTO 之间。以上是关于DDD:Dto 汇编器是不是应该成为域层的一部分?的主要内容,如果未能解决你的问题,请参考以下文章