【问题标题】:DDD: Loading whole aggregate would result in performance problemsDDD:加载整个聚合会导致性能问题
【发布时间】:2021-03-16 14:45:43
【问题描述】:

大多数 DDD 书籍(例如 DDD 的模式和原则)强烈建议在从数据库中获取数据时加载整个聚合。原因是聚合是一致的边界。
但在某些常见情况下,这会导致压倒性的性能问题。
这是我面临的一个真实示例:
我有一个聚合根,它是一个带有属性的 workobject 实体。此聚合中还有其他实体:

  1. 工作对象的附加documents 列表。每个document 都是一个实体。(document 类包含真实文档的元数据)。
  2. comments 列表。每个comment 都是一个实体`。
  3. activities 的列表。每个activity 都是一个实体,代表在此工作对象上完成的一项活动。
  4. ArchivedFiles 的列表。每个ArchivedFile 都是一个实体,它代表一个已经在外部系统中存档的文档。 (ArchivedFile 类包含真实归档文件的元数据)

这些实体属于聚合,因为workobject 上的更改也会主要影响这些实体的状态。
现在我有以下问题:
在 UI 中,用户可以在其中获取他/她的收件箱中的所有workobjects。这可能超过 100 个workobjects 甚至更多。但是此时为每个 workobject 加载整个聚合 (comments,activies,documents) 是没有意义的。这会降低应用程序的速度,从而导致糟糕的用户体验。
这个想法是在数据网格中只向用户显示workobject 的属性。如果用户进行特定事件,例如点击特定workobject,则加载特定表单,其中加载特定workobject的详细信息。这将是加载整个聚合的合适点(即comments、activiesdocuments)。但是大多数 DDD 书籍(例如 DDD 的模式和原则)警告不要在聚合内使用延迟加载,而是在加载聚合根时加载整个聚合。
我们应该如何通过仍然尊重 DDD 规则来解决这个问题?

【问题讨论】:

    标签: domain-driven-design


    【解决方案1】:

    我们应该如何通过仍然尊重 DDD 规则来解决这个问题?

    通常的答案:当你想要的是一个报告时,不要使用聚合模式。

    在执行域动态时,延迟加载是一种“代码味道”;如果您在进行更改时留下了大量数据,这强烈表明留下的信息属于一个不同的聚合。

    但是对于像报告这样的有效只读操作呢?我们不会更改任何内容,因此我们不需要确保我们的更改正确的约束,因此我们不需要用于描述约束的信息。

    有关分离读取和写入的更多想法,请查看 (“命令查询职责分离”)下描述的模式。

    【讨论】:

    • 我同意延迟加载可能是出于错误的原因并且可能会错误地绘制聚合边界。但是,如果不是在涉及修改聚合的每个业务事务期间访问聚合的所有子实体,则它不一定是异味。我自己默认不会使用延迟加载,但出于性能原因,它可能是合理的,并且非常适合写入密集型服务。当然,前提是聚合设计得当。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2017-12-10
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 2015-02-16
    相关资源
    最近更新 更多