简体   繁体   English

子聚合实体的域驱动设计存储库

[英]Domain Driven Design repository for child aggregate entity

After reading about DDD and Aggregates and taking a look at some StackOverflow posts like this在阅读了有关 DDD 和聚合并查看了一些像这样的 StackOverflow 帖子之后

Update an entity inside an aggregate 更新聚合内的实体

Some doubts about aggregates' responsibilities and repositories come to me.我对聚合的职责和存储库有一些疑问。

For example, if we supposed that we have user and address entities and one invariant that says that one user should only have a maximum of 3 addresses conforming by this way and Aggregate with those domain rules.例如,如果我们假设我们有用户和地址实体以及一个不变量,表示一个用户最多只能有 3 个符合这种方式的地址,并聚合这些域规则。

Taking into account this, it is supposed that when you conform that aggregate the access to the addresses child entity inside the user class will be always through user class methods, some methods like this will exist:考虑到这一点,假设当您符合聚合对用户 class 中地址子实体的访问时,将始终通过用户 class 方法进行访问,这样的一些方法将存在:

user.registerNewContactAddress("street blabl") user.updateContactAddress(address_id,"street blablb")... user.registerNewContactAddress("street blabl") user.updateContactAddress(address_id,"street blabl")...

In this basic scenario my questions are:在这个基本场景中,我的问题是:

1) It is supposed that should NOT exist an address repository, but, is it a mandatory rule or discouraged rule in all the cases? 1)假设不应该存在地址存储库,但是,在所有情况下它都是强制性规则还是不鼓励的规则?

I am thinking about the need to list all the addresses in the system, for example, obviously is more efficient to use an address repository that iterates across all the users and retrieves all their addresses.我正在考虑需要列出系统中的所有地址,例如,显然使用地址存储库更有效,该地址存储库遍历所有用户并检索他们的所有地址。

Or, for example, an user case that looking for "near" address.或者,例如,寻找“附近”地址的用户案例。

So, maybe an address repository with "only" methods "findAll" and "findXX" fit into DDD philosophy?那么,也许具有“唯一”方法“findAll”和“findXX”的地址存储库符合 DDD 哲学? Leaving the insertion and deletion of addresses managed by user Aggregate watching the invariant?留下由用户聚合管理的地址的插入和删除观察不变性?

2) What happens if, for example, instead of having a maximum of 3 addresses we have, 30.000 ( just a stupid case, I know, I'm sorry). 2) 例如,如果我们拥有的地址不是最多 3 个,而是 30.000 个(这只是一个愚蠢的案例,我知道,对不起),会发生什么情况。

In this case, should we conserve the user.changeAddress(address_id,"street blablb") method?在这种情况下,我们是否应该保留 user.changeAddress(address_id,"street blablb") 方法? I guess that it will become a little bit inefficient to retrieve the user and, in memory, iterate across all his addresses, so, it is another case where I see that maybe a direct call to address repository by ID is better.我想检索用户会变得有点低效,并且在 memory 中遍历他的所有地址,因此,在另一种情况下,我认为通过 ID 直接调用地址存储库可能更好。

Thanks谢谢

The use case you are describing is about reading all addresses of a user.您描述的用例是关于读取用户的所有地址。 For read operations it is not only allowed to have specific query operations that bypass the access of data through aggregates.对于读取操作,不仅允许具有绕过通过聚合访问数据的特定查询操作。 It is even encouraged.它甚至受到鼓励。 See also this answer to a similar question.另请参阅类似问题的答案。

Aggregates and repositories are optimized for write operations where business invariants need to be kept in tact.聚合和存储库针对需要保持业务不变性的写入操作进行了优化 To query data that is needed for read operations only (eg displaying data) the domain model, and thus aggregates and repositories, should be bypassed to optimize for reading the required data.要查询只需要读取操作(例如显示数据)的数据,应该绕过域 model 以及聚合和存储库,以优化读取所需数据。 If needed, this could even mean to have raw queries if an ORM does not provide the required performance.如果需要,如果 ORM 不能提供所需的性能,这甚至可能意味着进行原始查询。

Note : if you need to be able to manipulate actresses outside the context of a user (standalone) you might have missed a separate address aggregate.注意:如果您需要能够在用户上下文之外(独立)操纵女演员,您可能会错过一个单独的地址聚合。 In that case I would rather model Address as some reference type value object inside User , eg AddressId.在那种情况下,我宁愿 model Address作为User中的一些引用类型值 object,例如 AddressId。 Unless you need more data of an address in the context of the business logic executed by the User aggregate.除非您在用户聚合执行的业务逻辑上下文中需要更多地址数据。

And another note : in general, I would consider an Address to be a value object rather than an entity, unless you really share the same address "entity" across several users, which could be rather unlikely or necessary.另一个注意事项:一般来说,我会认为一个地址是一个值 object而不是一个实体,除非你真的在多个用户之间共享相同的地址“实体”,这不太可能或必要。 As the properties of an address alone allow to tell one address from another I would not see any need for an identity making it an entity.由于仅凭地址的属性就可以将一个地址与另一个地址区分开来,因此我认为不需要任何身份来使其成为一个实体。

Value objects are usually modelled as part of the aggregate.值对象通常建模为聚合的一部分。 In a relational database this could mean they get distributed across columns of the same table or for collections of value objects this is often done as serialized data, such as JSON. This also reduces potential performance worries as everything is queried from the same table.在关系数据库中,这可能意味着它们分布在同一个表的列中,或者对于 collections 个值对象,这通常作为序列化数据完成,例如 JSON。这也减少了潜在的性能担忧,因为所有内容都是从同一个表中查询的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM