应用程序服务责任与优化的DTO

时间:2018-10-24 15:36:33

标签: domain-driven-design aspnetboilerplate

我感到MPA ABP应用程序开发陷入三大原则,我认为这是DDD原则:

  • 应用程序服务不必绑定到控制器。我的意思是,控制器不必总是只使用一个应用程序服务。因为应用服务概念没有考虑到呈现
  • DTO必须满足视图需求,以最大程度地减少HTTP数据传输。因此,有时候我们必须针对每个实体/概念和针对每个视图设计一个DTO 类。
  • 应用程序服务获得,并且始终返回DTO。

现在,我有一个遵循“主-主”原理的视图:从实体列表中选择“主”部分中的一个实体,通过Ajax调用将“明细”部分中的实体详细信息加载。但是在“主”部分中的实体选择是通过 Ajax同步的下拉列表级联进行的:ParentEntities> Entities。

哪种选择尊重更好的DDD?

  1. 将GetAllParent(),GetAllEntities(parentId)和GetEntity(id)全部放入MyViewApplicationService 中,然后我的应用程序服务可以为我的视图需求返回优化的DTO,但违反了DDD原则
  2. 将这三种方法中的每一种都放在不同的应用服务中,在脑海中将更多“域”隔离开来,但是DTO是面向领域的,有些通用。因此, DTO尚未优化
  3. 让控制器负责将其映射到适合视图需求的DTO中,但不应这样做

2 个答案:

答案 0 :(得分:0)

我了解您的问题,让我们从头开始:

  

...将GetAllParent(),GetAllEntities(parentId)和GetEntity(id)全部放入MyViewApplicationService ...

商务人士会理解哪些词语?这些单词中有没有一个是普遍语言的一部分?

它们当然都是纯技术的,因此应该详细而不应该影响体系结构。基本上,它们会放在错误的位置,根本不应该看到它们。

  

...但是DTO是面向领域的,有些通用。因此DTO尚未优化...

DTO不应是任何远程面向对象的一部分。但是,您并不是说您想要对象导向,所以我们不要再赘述了。

仍然,如果您的对象应该是面向领域的,那么对于专门针对该领域编写的应用程序,它为什么不合适(未优化)?

我认为问题在于您的“对象”实际上在建模与域不同的东西。很有可能对数据库表或其记录进行建模。

我的意思是,如果您要显示产品的配置文件,那么您的“对象”应该是ProductProfile,而不是通用的Product。或ProductDetailsProductHeroImage,依此类推。 这些属于领域,并且可能在需求文档中也有提及。

  

让控制器负责映射到适合视图需求的DTO,但不应这样做。

为什么不应该这样做?如果功能的目的是向用户显示一些数据,那么为什么不将其视为“业务功能”。我的意思是应该从字面上反过来。 “视图”是您想要的业务功能,而数据库/存储库/控制器/服务或任何“只是”技术应该只是一个细节,而在体系结构中不可见。

免责声明:我必须承认,这些观点并不是DDD下大多数项目所做的事情,但是也许您会发现其中的含义,以便将来对这些项目提出更多质疑。:)

答案 1 :(得分:0)

  
      
  • 应用程序服务不必绑定到控制器。我的意思是,控制器不必总是只使用一个应用程序服务。   因为应用程序服务概念没有考虑到呈现。
  •   

应用程序服务不依赖于客户端类型,而是依赖于客户端需求。它们返回客户端所需的数据,因此从某种意义上说,应用程序服务考虑了客户端(表示)。

  
      
  • 应用程序服务始终获取和返回DTO。
  •   

并非总是如此。正如沃恩·弗农(Vaughn Vernon)在他的《实现DDD》(第512页)一书中所述,DTO有很多替代方案:

  • 介体

  • 域有效负载对象

  • 状态表示形式

  • 用例最佳存储库查询(与CQRS相似)

  • 数据转换器

  

哪种选择尊重更好的DDD?

     
      
  1. 将GetAllParent(),GetAllEntities(parentId)和GetEntity(id)都放入MyViewApplicationService中,然后我的应用程序服务可以返回   为我的视图需求优化了DTO,但违反了DDD原则,
  2.   

您不应使用客户端技术(MyView)来命名应用程序服务,而应根据其提供的功能来命名。

  
      
  1. 将这三种方法分别放在不同的应用程序服务中,将更多的“域”隔离开来,但是DTO是   面向领域,有点通用。因此DTO尚未优化。
  2.   

将3种方法放在一个服务中,或者每种方法有一个服务都没关系。控制器仍应调用它们。

  
      
  1. 让控制器负责将其映射到适合视图需求的DTO中,但不应这样做。
  2.   

如果您的意思是应用程序服务返回域对象,并且控制器将它们转换为DTO,则不会,在将域暴露给客户端时,您不应该这样做。