DDD:聚合中的延迟加载 [英] DDD: Lazy loading in aggregates

查看:248
本文介绍了DDD:聚合中的延迟加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去几天,我一直在学习DDD,并努力理解聚合根的一些核心概念。也许有人可以给我正确的方向,并阐述在这种情况下的最佳实践:

I've been learning DDD for the past few days and struggling to understand some core concepts of aggregate roots. Maybe somebody could give me push in the right direction and elaborate what's best practice in this scenario:

为使此示例不那么复杂,假设我们有两个实体的域:餐厅和营业时间。餐馆被定义为聚集根。

To make this example less complex, let's say we have a domain of two entities: restaurant and opening time. Restaurant is defined as aggregate root.

据我在所有在线示例中所了解的(如果我弄错了请更正),每次我需要一个实例时,聚合根都渴望加载所有子实体它。因此,每当我想在餐厅上调用方法时,所有的营业时间都会加载(无论是否使用)。

From what I understood in all the online examples (correct me if I'm mistaken), the aggregate root is eager loading all sub-entities every time I need an instance of it. So whenever I want to call call a method on the restaurant, all opening times are loaded (no matter if they are used or not).

在此示例中,我想确认在该餐厅增加了新时间后,营业时间就没有交叉点了。在这种情况下,每个其他开放时间的急切加载是有道理的,因为我需要将它们与现有开放时间进行比较。

In this example I want to verify that there is no intersection of opening times when a new time get's added to that restaurant. In this case the eager loading of every other opening time makes sense because I need to compare them with the existing ones.

但是:这有点限制,因为我知道每个我想添加另一个东西集合(比如餐厅图像)时,即使大多数方法只需要其中一个集合,SQL负载也越来越重。

BUT: this is kind of restricting because I know every time I want to add another collection of something (let's say restaurant images), the SQL load get's heavier and heavier even though most of the methods only require one of the collections.

我可以想到两种可能的解决方案:

I could think of two possible solutions:

延迟加载

延迟加载通过实体框架属性代理的开放时间/子实体。因此,聚合根可以存在而不必急于加载它们,但是只要需要它们,就可以访问它们。
但是,到处都是我在寻找答案的地方,我都发现将延迟加载到聚合根中被认为是不好的做法。也许有人可以解释为什么。

Lazy loading opening times / sub entities through entity framework property proxies. So the aggregate root can exist without eager loading them but whenever they are needed they can be accessed. However everywhere I was searching for an answer I've red that lazy loading in aggregate roots is considered bad practice. Maybe somebody could explain why.

较小的聚合根

我当然可以将开放时间本身定义为一个聚合根,但是接下来我需要将业务逻辑(在这种情况下为交叉路口验证)置于模型之外。

Of course I could define the opening time itself as an aggregate root but then I need to take the business logic (in this case the verification of intersections) outside of the model.

在以上所有示例中,我仅谈论命令端(而不是查询或序列化)。

In all the examples above I'm only talking about the command side (not querying or serializing).

也许我缺少一些基本想法。在此示例中,应该如何组织汇总根,为什么懒惰加载被认为是不好的做法?

Maybe I'm missing some fundamental ideas. How should the aggregate roots be organized in this example and why is lazy loading considered bad practice?

EDIT
不知道为什么这样由于基于观点,该问题被关闭。我要求最佳实践,以及为什么在这种情况下不进行延迟加载。

EDIT Not sure why this question was closed because of "opinion based". I'm asking for best practice and why lazy loading is not in this case.

推荐答案


但是到处都是我寻找答案的地方,我已经发现,将延迟加载到聚合根中是不明智的做法。

However everywhere I was searching for an answer I've red that lazy loading in aggregate roots is considered bad practice.

案件。实际的限制是由于直接引用,延迟加载其他聚合到聚合根。建议改用其标识符引用其他聚合。

That is not exactly the case. The actual restriction is for lazy loading other aggregates, due to direct references, at aggregate roots; referring other aggregates with their identifiers is recommended instead. This restriction has very good reasons behind it.

对聚合的引用不必要地增加了应用程序的内存占用量(检索将不在事务中使用的实体);在高度并发的使用案例中,其中有效的锁定会降低应用程序性能(不必要地锁定实体);

References to aggregates unnecessarily increases application's memory footprint (retrieving an entity that is not going to be used in a transaction); in highly concurrent use cases, where locks are in effect, degrades application performance (unnecessarily locking an entity); hampers data partitioning (both aggregates need to be processed in the same data node).

每个聚合根都定义了自己的一致性边界;这会妨碍数据分区(两个聚合都需要在同一数据节点中进行处理)。每笔交易旨在确保一个集合的一致性。通过域事件传达的跨集合的更新操作(或交易)应该是最终一致的

Each aggregate root defines its own consistency boundary; each transaction is meant to ensure one aggregate's consistency. Update operations (or transactions) across aggregates, communicated through domain events, are supposed to be eventually consistent.

如果要直接引用另一个聚合,从而需要延迟加载并对其进行更新,则应重新考虑您的设计。

If you are holding direct reference to another aggregate, thereby necessitating lazy loading, and performing updates on them, you should rethink your design.

通常情况下,方案中的选择,取决于业务环境或它处理的域。如果您认为 OpeninigTime 是一个单独的聚合,并且具有自己的一致性边界,则应仅保留其id并发布包含 OpeningTime 聚合将处理的ID的域事件。通过检索适当的汇总。但是,如果不是这种情况(似乎更有可能),则可以非常保留引用,延迟加载并对其进行更新。

The choice in your scenario, as usual, depends on the business context or the domain it deals with. If you think OpeninigTime is a separate aggregate, with its own consistency boundary, you should hold only its id and publish domain events, containing the id, that the OpeningTime aggregate will handle by retrieving the appropriate aggregate. If, however, it is not the case (that seems to be more likely), you may very much hold reference, lazy load, and perform updates on it.

这篇关于DDD:聚合中的延迟加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆