【问题标题】:Querying in a DDD system在 DDD 系统中查询
【发布时间】:2018-11-27 22:19:51
【问题描述】:

DDD 菜鸟在这里。假设我们有一个订单的域聚合(例如MS DDD Article)。使用此示例,我们要查询包含特定商品的所有订单。此外,我们对订单或项目中的所有内容并不真正感兴趣。只需 orderId、日期和项目名称就足以显示回用户/响应 API。正在努力解决以下问题:

  • 存储库(返回域对象)是否返回完整(即所有属性)匹配订单及其所有项目,然后域对象/服务必须过滤不感兴趣的项目?似乎效率很低,并且没有利用我们的持久性 (SQL) 引擎功能来缩小搜索范围。此外,此后续过滤将更改域对象的行为(例如订单状态及其总数),如果调用者使用此订单的数据/行为,则可能会导致副作用。
  • 或者存储库是否返回某种 DTO,它只具有调用者所需的数据属性?这似乎很有效,除了随着时间的推移,这个 DTO 列表可以增长到数百个满足系统中某些特定需求的类。看起来很丑。

这些担忧是否有效和/或是否有更好的方法?

【问题讨论】:

标签: domain-driven-design


【解决方案1】:

存储库模式来自 Eric Evans 的原始领域驱动开发一书。在第六章中,他讨论了在应用程序逻辑和存储关注点之间明确分离的优点。存储库的概念是,您将拥有一个接口,该接口支持您的所有域“聚合”对象都可以通过某处的内存集合访问的错觉。

聚合对象将封装与特定标识符关联的所有状态。从理论上讲,这意味着您将首先从存储库中获取聚合集合,然后枚举这些对象以组成响应来回答查询。

似乎效率很低,并且没有利用我们的持久性 (SQL) 引擎功能来缩小搜索范围。

是的。一些实现者尝试了让存储库接受查询对象作为参数的想法,以尝试解决这个问题。

另一种更具吸引力的方法是在存储库接口中构建更复杂的查询。也就是说,与其尝试创建一个统一的存储库接口,不如创建适合目的的接口——您可以查看存储库合约,并开始了解您的数据存储需要满足哪些类型的约束。

但最大的解锁部分是——意识到如果您处于读取用例中,您实际上并不需要这样的数据模型,您只需要做一些数据的不可变副本。所以完全跳过模型,只使用返回不可变 DTO 表示而不是“聚合根”的存储库。

这似乎很有效,但随着时间的推移,这个 DTO 列表可能会增长到数百个满足系统中某些特定需求的类。看起来很丑。

  • 有效
  • 很简单
  • 它显示了支持每个利基需求的实际成本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多