【问题标题】:Domain Driven Design which tables is a repository allowed to access领域驱动设计哪些表是允许访问的存储库
【发布时间】:2020-12-15 23:04:47
【问题描述】:

我想知道是否“允许”将聚合 A 与多个实体、值对象...保持在一起的存储库访问包含聚合 B 的表。示例如下。

我的系统是一个拥有多种产品的网上商店。 Product 是一个聚合根,所以我有一个 ProductRepository。那么单个Order 也是一个聚合根,其存储库OrderRepository。假设Order 聚合确实包含所有OrderLineItems

现在我的客户要求在网上商店中显示从未购买过的产品的部分。在 SQL 中,这将是这样的:

SELECT * FROM products p
WHERE NOT EXISTS (
  SELECT * FROM OrderLineItems o WHERE o.productId = p.id
)

对于ProductRepository 是否允许此查询,因为它只返回Products,还是不允许ProductRepository 使用此查询,因为它访问另一个聚合的数据?

【问题讨论】:

    标签: spring-data-jpa architecture repository domain-driven-design


    【解决方案1】:

    我个人会使用类似 CQRS 的方法来解决这类问题。将 DDD 聚合“仅”用于“写入”端,对于存储库类也是如此。

    为不改变状态的内容构建具体化视图和特定查询模型,例如您拥有的未售出产品查询。

    例如,您可以在改变状态(“写入”端)时使用存储库,例如当您保持订单时。

    当您必须查询未售出的产品时,您可以使用特定的查询处理程序来运行对数据库的直接查询(可能使用像 Dapper 这样的轻量级库)。

    【讨论】:

      【解决方案2】:
      • 当然是允许的
      • 我可能不会选择将其添加到 ProductRepository 自己

      需要注意的一个非常重要的事情是,我们在此处生成的是一个报告,也就是说,我们不会创建信息的本地副本,因为我们打算更改该信息。

      领域模型关注的是领域动态,也就是说控制我们的领域数据如何随时间变化的规则。如果我们不打算更改数据,那么也许我们不需要模型?

      因此,您最终可能会得到一个看起来像存储库的外观,但不是返回域实体/聚合根,而是仅返回您将通过网络发送的原始数据(例如,仅返回 html , csv, 或者你直接需要的json)。

      【讨论】:

      • 非常感谢您指出这是允许的,但可能不是最佳做法。我担心的正是我的存储库包含几个仅与前端查询需求相关的方法。我仍然感兴趣的是您提出的解决方案是什么?我在考虑 CQRS 将动态与静态视图分开。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多