让我们假设情景:
Users
系统User
都有Clients
(Client
始终分配给一个且只有一个User
)Users
上传不同的Documents
,Document
始终分配给一个Client
其中一项业务规则是,User
总共可以上传最多X Documents
,无论Clients
的数量是多少。
通过本书,我会使User
成为一个聚合根,其中包含Clients
的集合。然后,每个Client
都会为该特定客户端上传Documents
个集合。当User
尝试为给定的Document
上传新的Client
时,我们会加载Users
聚合根及其所有Clients
及其Documents
,在User
上我有类似的方法:
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加载到count&amp;比较它们。
将int documentsCount
放在User
上似乎违反了规则并引入了不必要的冗余。
这是否会引入单独的聚合根,如UserQuota
,我们只会加载所有Documents
的计数并进行检查?或者可能是一个值对象UserDocumentCount
,该服务将在User
对象上获取并调用方法:
boolean CanUploadDocument(UserDocumentCount count)
{
//compare to maximum allowed number of docs for User instance
return count < this.maxAllowedNumberOfDocuments;
}
什么是ddd-proper&amp;优化的方法来处理这个?
答案 0 :(得分:2)
拥有一个大的User aggregate
不是一个解决方案,但不是因为它很慢而且需要优化,因为它具有内部字段的凝聚力。
为了保护配额限制,User aggregate
只需要上传的文档,仅此而已。这表示您实际上有两个聚合,第二个是UserDocuments
及其方法uploadDocument
。此方法在内部检查引用不变量。作为优化,您可以保留int countOfDocumentsUploadedSoFar
方法中使用的uploadDocument
。这两个聚合只共享相同的身份(UserId
)。
注意:两个聚合之间不需要继承。
答案 1 :(得分:1)
像UserQuota
这样的介绍似乎是一个很好的解决方案。这个东西是一个真正的领域概念,它有权成为一个实体。刚才它有一个属DocumentsCount
,但是时间可能你需要LasDocumentUploadedTime
... MaxAllowedNumberOfDocuments
也可以成为配额的一部分,当这个数字发生变化和变化时它会有所帮助应该仅适用于新的配额,或者配额变得更加个性化。
您的域名操作也应该触及配额。例如,在上传文档时,您最初会读取相应的配额并进行检查,存储文档,然后更新配额。