Domain driven design 使用嵌套对象聚合根优化&;大收藏

Domain driven design 使用嵌套对象聚合根优化&;大收藏,domain-driven-design,Domain Driven Design,让我们假设一个场景: 我们有系统的用户 每个用户都有自己的客户端(客户端总是分配给一个且只有一个用户) 用户上传不同的文档,文档总是分配给一个且仅分配给一个客户端 其中一个业务规则是,用户可以总共上传X个文档,而不管客户端的数量如何 根据这本书,我将User作为一个聚合根目录,其中包含客户机的集合。然后,每个客户机都会为该特定客户机上载文档的集合。当用户尝试为给定的客户端上载新的文档时,我们将加载用户及其所有客户端及其文档的聚合根,在用户类上,我将有如下方法: boolean CanUpload

让我们假设一个场景:

  • 我们有系统的
    用户
  • 每个
    用户
    都有自己的
    客户端
    客户端
    总是分配给一个且只有一个
    用户
  • 用户
    上传不同的
    文档
    文档
    总是分配给一个且仅分配给一个
    客户端
  • 其中一个业务规则是,
    用户
    可以总共上传X个
    文档
    ,而不管
    客户端的数量如何

    根据这本书,我将
    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;
    }
    

    ddd处理这个问题的正确和优化的方法是什么?

    引入类似于
    用户配额的东西看起来是一个很好的解决方案。这是一个真正的领域概念,它有权成为一个实体。刚才它有一个属性
    documentscont
    ,但不久之后您可能需要
    LasDocumentUploadedTime
    MaxAllowedNumberOfDocuments
    也可以是配额的一部分,当此数字发生更改时会有所帮助,并且更改应仅应用于新配额,否则配额将变得更加个性化


    您的域操作也应该触及配额。例如,在上载文档时,您首先读取适当的配额并检查它,存储文档,然后更新配额。

    拥有一个大的
    用户聚合
    不是一个解决方案,但这并不是因为它速度慢并且需要优化,而是因为内部字段聚合

    为了保护配额限制,
    用户聚合
    只需要上传的文档,不需要更多。这表明您实际上有两个聚合,第二个聚合是
    UserDocuments
    及其方法
    uploadDocument
    。此方法在内部检查引号不变量。作为一种优化,您可以将
    uploadDocument
    方法中使用的
    int countofdocuments suploadedsofar
    。这两个聚合只共享相同的标识(用户ID


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

    谢谢您的回答!请你把你的第二段说清楚一点好吗?你认为一些服务应该检查配额然后运行文档上传,还是应该
    用户
    直接聚合根目录检查配额?@dee zg你能接受最终的一致性吗,或者文档的数量永远不会超过吗?@plalx不,我必须有很强的一致性。我不确定另一个关于文件数量永远不能超过的问题。你能稍微澄清一下吗?谢谢我想这是品味的问题。我更喜欢使用域服务来执行操作(这种方法有时称为贫血设计)。如果
    User
    拥有一个内部
    UserDocumentUploadPolicy
    实体,该实体还跟踪执行策略所需的状态,该如何办
    doc=user.uploadDocument(…);userRepo.save(用户);docRepo.save(doc)。在这里,
    uploadDocument
    可以执行类似于
    doc=newdocument(…);docUploadPolicy.applyForNewDocument(doc);退货单如果违反策略,策略将抛出的位置。我想,让策略成为一个单独的聚合,同时让用户使用工厂方法创建文档也是有意义的。您需要这个规则的一致性有多强?绝对的。任何用户上传的单个文档都不应超过其配额。在数据库端,它是一个具有乐观并发性的事务性写操作。在这种情况下,规则必须受到聚合的保护。您可以将计算的
    int documentscont
    存储为优化,但必须存储在
    UserAggregate
    中。这有什么特别的原因吗?询问,因为这会在数据库读取端引入不必要的复杂性,因为我不需要在
    UserAggregate
    上使用
    documentCount
    (除了
    User.UploadDocument()
    )的所有情况。为什么使用单独的
    UserQuota
    aggregate的想法不好?你能详细说明一下吗?谢谢因为在DDD中,聚合是最大的事务边界。如果你需要一个更大的,它们会使聚合变大(因此更慢)。注意2个聚合的标准,与优化问题无关。谢谢@迪兹,不客气。如果你还没有读过,你应该读一下:谢谢你的推荐!到目前为止还没有读过,但肯定会读的。
    boolean CanUploadDocument(UserDocumentCount count)
    {
      //compare to maximum allowed number of docs for User instance
      return count < this.maxAllowedNumberOfDocuments;
    }