5

Dabbling with domain driven design, I've run into a situation regarding how to identify aggregate roots within my domain model.

I have the following three classes, modelling a simple to-do list:

public class List {
    private IList<Task> _tasks;

    public List() { ... }
    public string Name { get;  set; } }
    public IEnumerable<Task> Tasks() { ... }
    public void AddTask(string descr) { ... }
    public void RemoveTask(Task t) { ... }
    public Task GetRandomTask() { ... }
}

public class Task {
    private IList<Update> _updates;

    public Task(string descr) { ... }

    public string Description { get; }
    public bool IsClosed { get; }
    public IEnumerable<Update> Updates() { ... }
    public void AddUpdate(string descr, bool close) { ... }
}

public class Update {
    public Update(string descr) { ... }
    public string Description { get; }
}

I can state the following about the model:

  1. An Update exists only within the context of a Task.
  2. A Task exists only within the context of a List.

List, therefore, would seem to be the only aggregate root. (Indeed my data access layer will only allow load/save of List objects.) However I can't see how I can cleanly push the UI that currently exists on my Task class, on to the List class. At the moment my List class is handing out references to Task objects, allowing the caller to modify them.

Does this imply that Task is also an aggregate root, even if it's existence is dependent on a containing List?

Thanks in advance.

rob
  • 1,154
  • 2
  • 12
  • 18
  • 2
    Related question: [DDD: Identifying aggregate root](http://programmers.stackexchange.com/questions/150196/). – Sergey Vyacheslavovich Brunov Aug 03 '16 at 00:12
  • Vaughn Vernon has a [3 part article](http://dddcommunity.org/library/vernon_2011) about aggregate design that might shed some light on your problem. - *[Iulian Margarintescu](https://stackoverflow.com/users/283930/iulian-margarintescu)* – Munim Munna Apr 14 '18 at 13:25

2 Answers2

1

In my opinion you can have either 1 or 2 aggregate in this cases. It's all depends your task in the list will be large or not; as well as your update will be large or not.

If task or update will not grow a lot, one aggregate root(List) will be fine.

Else you can separate them to two aggregate root(List, Task) where List can add Task and Task can add Update.

double-beep
  • 5,031
  • 17
  • 33
  • 41
Steve Chew
  • 11
  • 2
0

I think best ways to identify your aggregates are event storming or user story mapping.

Alireza Rahmani Khalili
  • 2,727
  • 2
  • 32
  • 33