在我看来,这可以被认为是一个非常主观的问题......我的建议是基于DDD实践。
在DDD 的上下文中,存储库应始终返回一个域对象(即Aggregate)。 聚合是数据存储传输的基本元素 - 您请求加载或保存整个聚合。 应用层将数据转换为对视图有意义的模型 /DTO。
解决您的疑虑:
您描述的选择列表示例非常适合 DTO。如果您创建一个 DTO 来表示两个属性以支持一个视图,那么您就是在创建一个 POCO 对象。这个对象是轻量级的并且创建起来很便宜。您可以使用 AutoMapper 等工具来辅助 DTO 和域模型之间的映射。当需要更改视图时,您的更改通常与 DTO 对象及其映射隔离。您还没有通过应用程序层将视图的概念泄漏到域层中。
-
DTO 将减少请求客户端的带宽成本(即,您不会返回具有 30 个属性的域实体并公开显示您的实体)
您可以使用单个存储库来支持您的部门选择列表
Department 实体的视图和 CRUD 操作。
使用一种域模型。但是,创建您需要支持来自该域模型或模型的视图的尽可能多的 DTO。
说到底,DDD 并不便宜,也不是灵丹妙药。
如果您有一个简单的问题要解决,请使用简单的 CRUD 和对您有意义的模型。这些只是指导方针...
DDD 对开发极其重要的软件很有意义
复杂性(有很多相关的业务规则)。和/或软件
有明确的未来,领域模型可以比
基础设施,或业务需求快速变化的地方。在
其他情况 DDD 可能带来比解决更多的意外复杂性。
对于它的价值,这里有一些关于 DDD 概念的补充说明,希望能有所帮助:
用例最优存储库查询:
Vaughn Vernon 将模式Use Case optimal Repository Queries 描述为......
与其读取多个不同类型的完整 Aggregate 实例,然后以编程方式将它们组合到单个容器中 (DTO or DPO),不如使用所谓的用例优化查询。这是您使用查找器查询方法设计存储库的地方,该方法将自定义对象组合为一个或多个Aggregate 实例的超集。查询动态地将结果放入Value Object (DDD) 中,专门设计用于满足用例的需求。
您设计的是值对象而不是 DTO,因为查询是域
特定的,而不是特定于应用程序的(例如 DTOS)。自定义使用
然后视图渲染直接使用案例最佳值对象。
这是使用CQRS的类似方法;但是,存储库是在您的统一域模型存储上执行的,而不是旨在支持您的只读视图的数据库。
沃恩弗农还说:
如果你发现必须创建很多finder方法来支持
多个存储库上的用例优化查询,它可能是一个
代码味道。
这可能是因为您误判了聚合边界并忽略了设计一个或多个不同类型聚合的机会。
Vaughn 将这种代码异味描述为:存储库掩码聚合错误设计
这也可能表明需要考虑使用CQRS。
DDD 查询模型(又名读取模型)
查询模型是非规范化的数据模型。它仅用于显示数据,而不是用于提供域行为。沃恩弗农说:
如果这种数据模型是 SQL 数据库,那么每个表都会保存
一种客户端视图(显示)的数据。表可以有
许多列,甚至是任何给定用户所需的列的子集
界面显示视图。表视图可以从表中创建,每个
其中用作整体的逻辑子集。
他还声明根据需要创建对许多视图的支持。值得注意的是,基于CQRS 的视图既便宜又一次性(用于开发和维护)。使用Event Sourcing,这种方法效果很好。
DDD DTO:
一种方法是让您的应用程序层组装DTOs。 DTO 将是您的域实体的子集的投影,以满足您的视图。
Vaughn Vernon 简单地说 -
DTO 旨在保存所有需要
显示在视图中
DDD 存储库
Martin Fowler 将存储库模式描述为:
在域和数据映射层之间使用
用于访问域对象的类集合接口。
请参考这些 SO 问题: