Domain driven design DDD-应实现哪一层DTO

Domain driven design DDD-应实现哪一层DTO,domain-driven-design,implementation,layer,dto,Domain Driven Design,Implementation,Layer,Dto,我正在学习DDD,如果我的问题太天真,我深表歉意。我认为我需要使用本地数据传输对象,以便向用户显示数据,因为许多属性不是任何实体/值对象的一部分 然而,我不确定这个DTO应该在哪里实现——在域层还是在应用程序服务层。DTO实现似乎是域的一部分,但这意味着当我在服务层中创建DTO集合并将其传递给表示层时,我必须在表示层中引用域层,这似乎是错误的 使用DDD原则实现DTO的正确方法是什么?将DTO定义为值来源所在的层 相对于OP的问题:将DTO放置在应用程序服务层中。DTO是该层的一个输出,如果您在

我正在学习DDD,如果我的问题太天真,我深表歉意。我认为我需要使用本地数据传输对象,以便向用户显示数据,因为许多属性不是任何实体/值对象的一部分

然而,我不确定这个DTO应该在哪里实现——在域层还是在应用程序服务层。DTO实现似乎是域的一部分,但这意味着当我在服务层中创建DTO集合并将其传递给表示层时,我必须在表示层中引用域层,这似乎是错误的


使用DDD原则实现DTO的正确方法是什么?

将DTO定义为值来源所在的层

相对于OP的问题:将DTO放置在应用程序服务层中。DTO是该层的一个输出,如果您在那里定义它,它是有意义的。不要将DTO放在域层中。域层不关心将事物映射到服务于外部层(域不知道自己的世界之外有一个世界)

表示层(靠近消费者)

  • 这可能是你的Api
  • 具有自己的模型或Dto定义,并具有与其层相关的属性。如果这是一个Api,那么Models/DTO具有用于格式化或数据类型验证的属性
  • 这是“应用程序根”(意味着它必须同时引用域服务层和数据/基础设施层才能注入服务)
  • 在ApplicationService.Dto和Presentation.Dto之间映射数据
应用服务层

  • 有自己的Dto定义,可以在不公开域实体的情况下返回数据
  • 表示层和域层之间的桥梁
  • 包含应用程序服务。有关应用程序服务的详细定义,请参见答案
域层

  • 域实体
  • 可能包含桥接基础架构层的接口,用业务部门能够理解的词语定义,不受技术术语的限制(例如:IExcelReport、iGoogle HeetReport、IRepository)
  • 可能包含“域服务”
数据/基础架构层(离您的数据库或外部服务最近)

  • 数据库基础设施(映射)
  • Excel库,如果将此层定义为基础结构代码
  • 邮件或通知服务
  • PDF输出文件

Yorro关于在何处放置DTO是正确的,但我鼓励您避免“DTO心态”。这种思维方式与DDD的思维方式相冲突

考虑“我需要一个DTO”就是考虑技术代表性(正如plalx所说);这是一个太低的抽象层次。尝试更高层次的abtraction,并考虑您的域、用户任务和UI

是否需要向用户获取视图数据?通过返回特定YourViewInfo类的视图服务将其带到UI

您是否需要向某些服务发送数据以执行任务?向其发送特定的TaskMessageInfo类或特定的命令类

当您开始对这些类的内部进行建模时,您应该开始考虑它的技术表示;然后,您可以得出这样的结论,即,为了方便起见,可以使用DTO类

以这种方式思考可以帮助您对系统进行建模,而不会引发类似这样的问题

这东西放在哪里或属于哪里


DTO和域是不同的层。
因此,它需要从一个映射到另一个,通常在所谓的应用程序服务层中完成。
请阅读以下文章,以更深入地了解DTO和分层:


此类暴露于外部世界的DTO成为合同的一部分。根据它们的形式,应用程序层或表示层是它们的好位置

如果DTO仅用于表示目的,那么表示层是一个不错的选择

如果它们是API的一部分,无论是用于输入还是输出,这都是应用层的问题。应用层是将域模型与外部世界连接起来的层

有趣的是,表示层应该只通过应用层访问域模型。否则,我们将失去单一访问点——我们将有多个层调用域模型。应用层公开了我们所有的用例。它们是由来自另一个服务的调用调用还是由表示层调用,差别不大

来源 我从沃恩·弗农那里学到的这些概念的核心。(我想引用它,但我手头没有。)关于应用层和表示层的章节是相关的

首先,我的结论来自严格遵守Eric Evans和Vaughn Vernon提出的概念,并在领域模型中优先考虑自由,因为这是领域驱动的设计:

  • 域模型应该易于更改。这意味着不在外部公开域对象,因为有外部依赖项会使它们很难更改(而不会破坏它们)
  • 应用层是外部访问点。它定义了域模型上的用例。这意味着不从其他地方操作域模型。表示层只能通过应用层。没有人喜欢处理许多不同的访问点
为什么您认为DTO是域的一部分?DTO是一种可序列化友好的技术表示。感谢您的所有回答。这让我的头脑更加清晰。你的观点仅仅是用了一个不同的名字吗?YourViewInfo而不是YourViewDTO?@MarkusPscheidt否。我的观点是在dom中