Suppose I have a User
entity with name
and age
attributes. A User
can own Box
es. A Box
has the name
and color
attributes. Business rules dictate that one User
can own at most 5 boxes. So, in this case, the User
can be the aggregate root and whenever a new Box
is bought by a User
, I can do
class User {
private boxes: Box[];
private MAX_BOXES = 5;
// snip
addBox(Box box) {
if (this.boxes.count > MAX_BOXES) {
throw new BoxLimitException();
}
this.boxes.add(box);
}
}
However, when I want to edit one Box
's (or a User
, for that matter) attributes, the box limit business rule is no longer needed so I should be able to just modify it directly, without going through the aggregate, i.e.:
box->paint(GREEN);
But, according to what I've read on DDD, you're not supposed to do that, since you're breaking the bounded context of the aggregate root. Should I have different Box
entities depending on the use case? Specially since a Box
might have its own business rules independent of those of a User
aggregate.
I already asked a similar question, but it got no answers, so I tried with this new, simpler example, to better explain my doubts.
User
needs aBox
collection at all! It could (and I'd argue should) be modeled such that theUser
only needs aprivate numberOfBoxes: int
property to enforce our single invariant. In this way we can avoid the "problem" you lay out entirely.numberOfBoxes
property you suggest, how would I go about adding a Box to the user? In my service I'd have to load the repository for both the User and the Box, and doing the invariant check on the User aggregate, and afterwards persist the Box aggregate. Is that right? I know better than following methodologies blindly rather than pragmatically, but DDD seems so rigid that I have these kind of doubts pretty much every time I have to model anything.