使用嵌套对象和根聚合根优化大收藏 [英] Aggregate root optimization with nested objects & big collections
问题描述
让我们假设情况:
- 我们有系统的
用户
- 每个
User
都有其Clients
(Client
始终分配给一个,并且只有一个User
) -
用户
上传不同的Documents
,并且始终将一个Document
分配给一个,并且只有一个Client
- We have
Users
of the system - Each
User
have theirClients
(Client
is always assigned to one and only oneUser
) Users
upload differentDocuments
and aDocument
is always assigned to one and only oneClient
业务规则之一是, User
最多可以总共上传X个 Documents
,而与 Clients
的数量无关.
One of the business rules is that User
can upload up to X Documents
in total, regardless of number of Clients
.
在这本书中,我将使 User
成为聚合根,其中将包含 Clients
的集合.然后,每个 Client
都会为该特定客户端上载 Documents
的集合.当 User
尝试为给定的 Client
上传新的 Document
时,我们将使用其所有客户
和他们的文档
,在 User
类上,我将使用类似以下方法:
By the book, i would make User
an aggregate root which would contain collection of Clients
. Then each Client
would have collection of Documents
uploaded for that particular client. When User
attempts to upload new Document
for given Client
, we would load Users
aggregate root with all of its Clients
and their Documents
, and on User
class i'd have method like:
boolean CanUploadDocument()
{
int numberOfDocuments = //Iterate Clients and sum up total number of their documents;
//compare to maximum allowed number of docs for User instance
return numberOfDocuments < this.maxAllowedNumberOfDocuments;
}
一切都很好,但是 maxAllowedNumberOfDocuments
可以是成千上万,而将它们全部从db加载以计数&比较它们.将 intdocumentCount
放在 User
上似乎违反了规则并引入了不必要的冗余.
All well and good, but maxAllowedNumberOfDocuments
can be thousands or tens of thousands and it feels like a huge overkill to load them all from db just to count & compare them.
Putting int documentsCount
on User
seems like breaking the rules and introducing unnecessary redundancy.
是不是要引入像 UserQuota
这样的单独的聚合根,我们只在其中加载所有 Documents
的计数并进行检查?或者可能是一个值对象 UserDocumentCount
,该服务将获取该值对象并调用 User
对象上的方法:
Is this the case to introduce separate aggregate root like UserQuota
where we would load just count of all Documents
and do the check? Or maybe a value object UserDocumentCount
which service would get and call method on User
object:
boolean CanUploadDocument(UserDocumentCount count)
{
//compare to maximum allowed number of docs for User instance
return count < this.maxAllowedNumberOfDocuments;
}
什么是ddd-proper&优化的方式来解决这个问题?
What is the ddd-proper & optimized way to handle this?
推荐答案
拥有庞大的用户集合
不是解决方案,但不是因为它运行缓慢且需要优化,而是因为内部领域的凝聚力.
Having a big User aggregate
is not a solution but not because of the fact that it is slow and it needs an optimization, it's because of the internal fields cohesion.
为了保护配额限制,用户汇总
仅需要上传的文档,仅此而已.这表明您实际上有两个聚合,第二个是 UserDocuments
及其方法 uploadDocument
.此方法在内部检查引号不变量.作为一种优化,您可以保留 uploadDocument
方法中使用的 int countOfDocumentsUploadedSoFar
.这两个聚合仅共享相同的身份( UserId
).
In order to protect the quota limit the User aggregate
needs only the uploaded documents and nothing more. This is a sign that you have in fact two aggregates, the second being UserDocuments
with its method uploadDocument
. This method internally checks the quote invariant. As an optimization, you could keep a int countOfDocumentsUploadedSoFar
that is used in the uploadDocument
method. The two aggregates share only the same identity (the UserId
).
注意:两个聚合之间不需要继承.
Note: no inheritance is needed between the two aggregates.
这篇关于使用嵌套对象和根聚合根优化大收藏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!