使用嵌套对象和根聚合根优化大收藏 [英] Aggregate root optimization with nested objects & big collections

查看:84
本文介绍了使用嵌套对象和根聚合根优化大收藏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设情况:

  1. 我们有系统的用户
  2. 每个 User 都有其 Clients ( Client 始终分配给一个,并且只有一个 User )
  3. 用户上传不同的 Documents ,并且始终将一个 Document 分配给一个,并且只有一个 Client
  1. We have Users of the system
  2. Each User have their Clients (Client is always assigned to one and only one User)
  3. Users upload different Documents and a Document is always assigned to one and only one Client

业务规则之一是, 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屋!

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