使用嵌套对象聚合根优化&大集合

时间:2017-12-14 10:40:36

标签: domain-driven-design

让我们假设情景:

  1. 我们有Users系统
  2. 每个User都有ClientsClient始终分配给一个且只有一个User
  3. Users上传不同的DocumentsDocument始终分配给一个Client
  4. 其中一项业务规则是,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;优化的方法来处理这个?

2 个答案:

答案 0 :(得分:2)

拥有一个大的User aggregate不是一个解决方案,但不是因为它很慢而且需要优化,因为它具有内部字段的凝聚力。

为了保护配额限制,User aggregate只需要上传的文档,仅此而已。这表示您实际上有两个聚合,第二个是UserDocuments及其方法uploadDocument。此方法在内部检查引用不变量。作为优化,您可以保留int countOfDocumentsUploadedSoFar方法中使用的uploadDocument。这两个聚合只共享相同的身份(UserId)。

注意:两个聚合之间不需要继承。

答案 1 :(得分:1)

UserQuota这样的介绍似乎是一个很好的解决方案。这个东西是一个真正的领域概念,它有权成为一个实体。刚才它有一个属DocumentsCount,但是时间可能你需要LasDocumentUploadedTime ... MaxAllowedNumberOfDocuments也可以成为配额的一部分,当这个数字发生变化和变化时它会有所帮助应该仅适用于新的配额,或者配额变得更加个性化。

您的域名操作也应该触及配额。例如,在上传文档时,您最初会读取相应的配额并进行检查,存储文档,然后更新配额。