具有实体树的域聚合根

Sys*_*ank 2 tree entity design-patterns domain-driven-design cqrs

我的聚合根Node的一个属性是一棵类似树的实体组Task。喜欢

- Node
    - Name
    - Release
    - User
    - task
       - task
       - task
            - task
       - task
Run Code Online (Sandbox Code Playgroud)

任务树可能非常大,因此不会完全加载到内存中。我可以实现某种类型的对象延迟加载或动态查询。此外,我需要一种简单的方法来使用 Task::addSubtask 这样的函数添加新任务...但我的直觉告诉我,这些解决方案在很多层面上都是错误的。

我试图从这个问题中吸取一些关于 DDD 的教训。所以我想找到这些假设的证实。

  1. Any aggregate root should always be fully loaded. Any partial load will require a subcomponent to be able to perform a query (through a repo, stored query...) which would brake many rules: single responsibility, ignorance of persistance mechanisms... (NOTE: I do not have an ORM layer providing lazy loading by default)

  2. The "tree shape" of tasks in memory is actually only necessary for the Outline view in the GUI. Therefore I should have a dummy composite which can perform queries to the Service Layer of my Domain Model.

  3. Since there is no reason to have a Task outside the context of a Node, my node repository should deal with any operation requiring the tree exploration, like:

    (List*) findChildrenOfTask(Task* aTask)

    (List*) findChildrenOfTask(Task* aTask, String regexInText)

    (void) addChildToTask(Task* aTask)

These are my assumptions, but I would like to confirm them with someone with more experience doing DDD. The "tree only in the GUI" also seems to spur some ideas of CQRS ideas. Is this problem one example of the benefits adopting CQRS for DDD?

Mge*_*etz 5

Vaughn Vernon 的书《实现领域驱动设计》实际上讨论了这个确切的示例

也就是说,我邀请您思考以下问题:

  • 任务是否需要与 Node 保持事务一致?如果不是,它可以是它自己的聚合,这大大简化了事情。请记住,您只是从命令的角度考虑这个问题。
  • 如果树仅用于查询,为什么不让 DTO 担心这一点而不是损害您的域模型?

我完全承认弗农在解释这一点上比我做得更好。