与领域驱动设计相关的聚合根和UI检索

本文关键字:检索 UI | 更新日期: 2023-09-27 18:29:11

我正在努力掌握越来越多的领域驱动设计并遵循最佳实践。到目前为止,我的理解是:

  • 聚合是相互关联的实体的集合
  • 聚合的根是将聚合关系绑定在一起的实体
  • 如果删除了根,则聚合范围内的所有内容也必须删除
  • 聚合根只能通过身份相互引用

我的问题是:

如果我有多个彼此相关的聚合,比如订单和产品类别。

应用程序服务应该如何处理订单和相关产品类别的检索?

服务是否应该引用订单和产品类别的每个存储库,首先检索订单,然后检索产品类别,最后填写一个引用两者信息的数据传输对象?

类似这样的东西:

public OrderDto GetOrder(int id)
{
    var order = _orderRepo.GetById(id);
    var productCategory = _categoryRepo.GetById(order.ProductCategoryId);
    return new OrderDto 
                  { 
                     CustomerName = order.CustomerName, 
                     ProductCategoryName = productCategory.Name,
                     *..etc..*
                  };
}

或者,如果根是紧密相关的,那么保持它们解耦是过度扼杀吗?

或者UI应该调用独立的服务来获得完整的画面?

与领域驱动设计相关的聚合根和UI检索

根据的"违反规则的原因"部分,在某些情况下您可能不得不违反规则

第一个是预置方便,当你只需要一次显示一个订单时,这并不是什么大不了的,但如果你需要列出订单,你提到的解决方案会导致N+1查询问题。

另一种解决方案是坚持规则,使用持久性对象来呈现ui(在列表顺序的情况下)。如果你想将域模型与持久性基础设施分离(或已经分离),可以在这里找到一些讨论。

在应用程序中使用CQRS模式似乎是一种选择。这种模式非常适合DDD,因为在这种情况下,我们需要一种不同的写入和读取数据的机制,它可以帮助我们,您可以在本文中阅读更多关于CQRS的信息https://martinfowler.com/bliki/CQRS.html,因此,如果您想检索用于显示的数据,则不需要获取所有聚合根,因为在读取数据时,实体的不变性不会无效,即实体状态不会改变。