How to define DDD Aggregate root for hierarchical data structure?

眉间皱痕 提交于 2019-12-10 10:43:15

问题


I'm currently trying to adapt Domain-driven-design principles to my development practices. And I have stuck on how to define an aggregate root for data that are organized in hierarchies.

Let's take for instance folder structure - each folder can have 0..N sub-folders, and sub-folder 0..N can also have 0..N sub-folders and so on.

I have invariants on a folder and all it's direct and indirect subfolders - deleting folder should result in deleting all of it's sub-folders

Would that be DDD valid approach to have let's say Aggregate root "Folder hierarchy", that contains 1 "Folder" entity (that would be "header" folder for that folder hierarchy) and each Folder entity has 0..N Folder entities (sub-folders)

Would that be a valid DDD? Would that be effective? Since I have read that DDD advocates to have small Aggregates, but this "Folder Hierarchy" would potentially be a huge aggregate...

Is Aggregate Root with Deep Hierarchy appropriate in DDD?

Effective Aggregate Design by Vaughn Vernon

Any advice how to make this both DDD valid and effective?

EDIT

Let's have a bit different example of objects that have tree-like structure. Let's say I need to develop a task tracking system and this system needs tasks to have sub-tasks non-fixed levels deep - all tasks are from functionality/behaviour perspective the same - each task can have 0..1 parent task and 0..N child tasks.

Having Task as an aggregate root (with all it's child-task hierarchy) would not follow DDD recommendation's to have small Aggregates - right?

What would be a good design for Task according to DDD principles? And how to implement invariants on a Task (with all it's child-task hierarchy) if Task (with it's hierarchy) is not an aggegate?


回答1:


You should model your aggregates around invariants. One rule of thumb is that aggregate should be loaded in one go to memory (with all it's child objects) no lazy loading.

Do you really have an invariant that requires whole hierarchy to be loaded? Is there situation where you need to traverse all nodes in hierarchy? To answer this question you need to think about use cases of your aggregate.

If you need all data then your aggregate has proper size it just couldn't be smaller. If your invariant require only small portion of graph then maybe you are missing some domain concept that will describe this graph part.

If you care only about updating time of ancestors then perhaps your task can contain only Parent property you don't need child collection. Then you can perform things like

public void RegisterTime(TimeSpan time)
{
    TimeSpent += time;
    // maybe more stuff here
    Parent.RegisterTime(time)
}

Then your repository will get only Task with all of his ancestors and aggregate will be small enough.

I'm just guessing because it always depends of use cases.



来源:https://stackoverflow.com/questions/31964787/how-to-define-ddd-aggregate-root-for-hierarchical-data-structure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!