We have a aggregate root as follows.
@AggregateRoot
class Document {
DocumentId id;
}
The problem statement given by the client is "A document can have multiple document as attachments"
So refactoring the model will lead to
//Design One
@AggregateRoot
class Document {
DocumentId id;
//Since Document is an aggregate root it is referenced by its id only
Set<DocumentId> attachments;
attach(Document doc);
detach(Document doc);
}
But this model alone won't be sufficient as the client wants to store some meta information about the attachment, like who attached it and when it was attached. This will lead to creation of another class.
class Attachment {
DocumentId mainDocument;
DocumentId attachedDocument;
Date attachedOn;
UserId attachedBy;
//no operation
}
and we could again refactor the Document model as below
//Design Two
@AggregateRoot
class Document {
DocumentId id;
Set<Attachment> attachments;
attach(Document doc);
detach(Document doc);
}
The different possibilities of modeling that I could think of are given below.
- If I go with design one then I could model
Attachment
class as an aggregate root and use Events to create them whenever a Document is attached. But it doesn't look like an aggregate root. - If I choose design two then
Attachment
class could be modeled as a value object or an entity. - Or If I use CQRS, I could go with design one and model
Attachment
as a query model and populate it using Events.
So, which is the right way to model this scenario? Is there any other way to model other what I have mentioned?