为了账号安全,请及时绑定邮箱和手机立即绑定

为什么不使用存储库返回部分域模型结果

为什么不使用存储库返回部分域模型结果

C#
繁花不似锦 2021-04-30 13:08:18
我看过几篇文章,指出存储库只应为诸如GetAll()之类的方法调用返回完整的域模型。但是,如果我只需要一个列表,其中每个项目仅由来自具有30个属性的域模型中的2个属性组成,该怎么办?我想显示一个列表部门,其中列表仅显示部门名称和位置。用户可以从该列表中选择一个部门并请求其详细信息。从那里,我可以进行另一个存储库调用,以返回所选内容的完整域模型,并允许进行典型的操作。但是,如果我不应该使用存储库返回完整域模型的子集,那么建议的方法是什么?我想我只可以返回完整域模型的列表,但这似乎浪费了网络带宽,无法通过网络传输如此多的数据。如果我创建另一个模型来表示感兴趣的2个属性,那么这似乎又是一件繁重的工作,因为每个模型我都有自己的存储库和用于访问存储库的服务模块。从存储库中检索完整域模型的子集的建议方法是什么?另外,如果我违反了仅通过提取部分模型数据(仅用于选择列表)仅提取完整模型的规则,将会发生什么情况。
查看完整描述

1 回答

?
冉冉说

TA贡献1877条经验 获得超1个赞

我认为,这可以被认为是一个非常主观的问题。...我的建议是基于DDD实践的。

在的上下文中DDD,存储库应始终返回域对象(即Aggregate)。聚合是数据存储传输的基本元素-您请求加载或保存整个聚合。 取决于应用程序层将数据转换为模型/DTO对视图有意义。

要解决您的问题:

  1. 您描述的选择列表示例非常适合DTO。如果您创建一个DTO来表示两个属性来支持一个视图,那么您正在创建POCO对象。该对象重量轻且创建成本低。您可以使用诸如AutoMapper之类的工具来协助DTO与域模型之间的映射。当需要更改视图时,通常会将更改隔离到DTO对象及其映射。您尚未通过应用程序层将视图的概念泄漏到域层中。

  2. DTO将减少请求客户端的带宽成本(即,您不返回具有30个属性的域实体,并在公共场合显示您的实体

  3. 您可以使用单个存储库来支持部门实体的部门选择列表视图和CRUD操作。

  4. 使用一个域模型。但是,创建所需的许多DTO来支持该域模型或多个模型的视图。

归根结底,DDD并不便宜,也不是灵丹妙药。

如果您有一个简单的问题要解决,则可以将简单的CRUD与对您有意义的模型一起使用。这些只是指导方针...

DDD对于开发极其复杂的软件(具有许多相关的业务规则)是有意义的。和/或前途光明的软件,域模型可以使基础架构的寿命更长,或者业务需求的变化很快。在其他情况下,DDD可能带来比解决更多的意外复杂性。


值得一提的是,这里还有一些有关DDD概念的补充说明,希望对您有所帮助:

用例最佳存储库查询:

Vaughn Vernon将模式描述Use Case optimal Repository Queries为...。与其读取多个不同类型的整个Aggregate实例,然后以编程方式将它们组合到一个容器(DTO or DPO)中,您可能不希望使用所谓的用例最佳查询。在这里,您可以使用查找器查询方法设计存储库,这些查询器方法将自定义对象组成一个或多个Aggregate实例的超集。该查询将结果动态地放入Value ObjectDDD)特别设计中,以解决用例的需求。

您设计一个值对象而不是DTO,因为查询是特定于域的,而不是特定于应用程序的(例如DTOS)。然后,自定义用例最佳值对象由视图渲染器直接使用。

这是与使用类似的方法CQRS;但是,存储库是在统一域模型存储中执行的,而不是在设计用于支持只读视图的数据库中执行的。

沃恩·弗农(Vaughn Vernon)还指出:

如果发现必须创建许多查找程序方法来支持对多个存储库的用例最佳查询,则可能是代码的味道。

这可能是因为您错误地判断了聚合边界,而忽略了设计一个或多个不同类型聚合的机会。

Vaughn将此代码气味描述为:存储库掩码聚合错误设计

这也可能表明需要考虑使用CQRS

DDD查询模型(又名读取模型)

查询模型是非规范化数据模型。它仅用于显示数据,并不用于传递域行为。沃恩·弗农(Vaughn Vernon)指出:

如果这种数据模型是SQL数据库,则每个表将保存用于一种客户端视图(显示)的数据。该表可以包含许多列,甚至是任何给定用户界面显示视图所需的那些的子集。可以从表创建表视图,每个表都用作整体的逻辑子集。

他还声明将根据需要创建对许多视图的支持。值得注意的是,CQRS基于视图的视图既便宜又可以一次性使用(用于开发和维护)。使用Event Sourcing,可以很好地配合这种方法。

DDD DTO:

一种方法是组装您的应用程序层DTOs。这DTO将是一个或多个域实体的子集的投影,以满足您的视图。

沃恩·弗农(Vaughn Vernon)简单地指出-

DTO旨在容纳视图中需要显示的全部属性

DDD资料库

Martin Fowler将存储库模式描述为:

使用类似集合的接口访问域对象,在域和数据映射层之间进行中介。

请参考以下SO问题:


查看完整回答
反对 回复 2021-05-08
  • 1 回答
  • 0 关注
  • 123 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信