Should lookup values be modeled as aggregate roots?
Asked Answered
B

4

12

As part of my domain model, lets say I have a WorkItem object. The WorkItem object has several relationships to lookup values such as:

WorkItemType:

  • UserStory
  • Bug
  • Enhancement

Priority:

  • High
  • Medium
  • Low

And there could possibly be more, such as Status, Severity, etc...

DDD states that if something exists within an aggregate root that you shouldn't attempt to access it outside of the aggregate root. So if I want to be able to add new WorkItemTypes like Task, or new Priorities like Critical, do those lookup values need to be aggregate roots with their own repositories? This seems a little overkill especially if they are only a key value pair. How should I allow a user to modify these values and still comply with the aggregate root encapsulation rule?

Buddleia answered 13/10, 2012 at 6:39 Comment(0)
T
6

Landon, I think that the only way is to make those value pairs aggregate roots. I know that is might look overkill, but that's DDD braking things into small components.

The reasons why I think using a repository is the right way are:

  • A user needs to be able to add those value pairs independently of a Work Item.
  • The value pairs don't have a local, unique identity

Remember that DDD is just a set of guidelines, not hard truths. If you think that this is overkill, you might want to create a lookup that returns the pairs as value objects. This might work out specially if you don't have a feature to add value pairs in the application, but rather through the database.

As a side note, good question! There are quite a few blog posts about this situations... But not all agree on the best way to do this.

Tremayne answered 13/10, 2012 at 8:9 Comment(1)
In my case, the application does need to modify the lookup values. I guess modeling these objects as aggregates seems to make sense. Vaughn Vernon has an explanation of how these aggregates can work together in this article. At the bottom of page 8 he mentions that you could have an application service resolve the dependencies. He also states that if the queries become too costly you could use some CQRS.Buddleia
M
8

While the repository pattern as described in the blue book does emphasize its use being exclusive to aggregates, it does leave room open for exceptions. To quote the book:

Although most queries return an object or a collection of objects, it also fits within the concept to return some types of summary calculations, such as an object count, or a sum of a numerical attribute that was intended by the model to be tallied. (pg. 152)

This states that a repository can be used to return summary information, which is not an aggregate. This idea extends to using a repository to look up value objects, just as your use case requires.

Another thing to consider is the read-model pattern which essentially allows for a query-only type of repository which effectively decouples the behavior-rich domain model from query concerns.

Mirtamirth answered 13/10, 2012 at 17:43 Comment(1)
+1 for pointing out that a Repository doesn't always have to return an aggregate root. Also for the link to the read-model pattern and explaining how it differs from CQRS because it shares the same database. Since my application requires data changes and not just reads, I've decided to make them aggregate roots and probably use a read model or application service to make the associations between the aggregates.Buddleia
T
6

Landon, I think that the only way is to make those value pairs aggregate roots. I know that is might look overkill, but that's DDD braking things into small components.

The reasons why I think using a repository is the right way are:

  • A user needs to be able to add those value pairs independently of a Work Item.
  • The value pairs don't have a local, unique identity

Remember that DDD is just a set of guidelines, not hard truths. If you think that this is overkill, you might want to create a lookup that returns the pairs as value objects. This might work out specially if you don't have a feature to add value pairs in the application, but rather through the database.

As a side note, good question! There are quite a few blog posts about this situations... But not all agree on the best way to do this.

Tremayne answered 13/10, 2012 at 8:9 Comment(1)
In my case, the application does need to modify the lookup values. I guess modeling these objects as aggregates seems to make sense. Vaughn Vernon has an explanation of how these aggregates can work together in this article. At the bottom of page 8 he mentions that you could have an application service resolve the dependencies. He also states that if the queries become too costly you could use some CQRS.Buddleia
K
3

Not everything should be modeled using DDD. The complexity of managing the reference data most likely wouldn't justify creating aggregate roots. A common solution would be to use CRUD to manage reference data, and have a Domain Service to interface with that data from the domain.

Kephart answered 13/10, 2012 at 9:3 Comment(0)
S
2

Do these lookups have ID's ? If not, you could consider making them Value Objects...

Shaylashaylah answered 15/10, 2012 at 10:26 Comment(1)
They have IDs and are shared by different entity instances so they aren't Value Objects.Buddleia

© 2022 - 2024 — McMap. All rights reserved.