Currently we are designing a system where a user can comment on multiple subjects. Subjects can be a picture, a post, etc. A comment should be editable and deletable. It would just contain text (for now). A comment can only be placed if the subject allows it. On the first hand, I would model it as follows:

| Comment  (AR) |
| - Subject     |
| - Text        |

| Subject (VO)  |
| - PictureID   |
| - PostID      |

However the problem is that the comment-service needs to be able to know whether the user is allowed to comment on a certain Picture or Post (depending on privacy setting, f.e). So it needs to know about the Subject entities. Also the sentence A user can comment on a Post OR a Picture makes me question whether the Comment should be an AR itself. Wouldn't this make the comment an aggregate of the root-aggregates Picture and Post? Like this:

| Post (AR)    |
| CommentIDs[] |
| ...

| Picture(AR)  |
| CommentIDs[] |
| ... 

| Comment  (AR) |
| - Text        |

But now, by putting the comments inside Post and Picture would blow up these aggregates and create huge trx-boundaries when big discussions start. I'm a bit lost here, and keep circling between these 2 models.


Object creation patterns can be tricky.

That said, I see nothing in your rules indicating that it is necessary for a Picture/Post to need any reference to their List<CommentId>. For example:

comment = picture.addComment( text );

seems like an acceptable, domain-centric way of creating a new Comment according to rules specified by the subject (Picture/Post).


I think your core problem is you’re confusing your DB model with your Domain Model, and trying to map each DB row to exactly one class.

There are two contexts at play here. You’re either viewing a Subject and its Comments, or you're editing a Comment (One could argue that editing a Subject is a third, but the point is you’re never editing a Subject and a Comment at the same time).

When viewing the Subject, the Comment can be a value object CommentVO. This Value Object doesn’t need all the behavior that a real Comment Aggregate Root would have, and probably not even all the same properties.

When editing a Comment, you need the CommentAR version that has behavior.

These two classes can be mapped to the same DB table since the VO never makes any changes.

Having your Subject own a list of CommentVOs allows it to manage its sub entities as necessary, and your object graph doesn't get dangerously tall. You only allow editing of a CommentAR since it has the validation and other behavior necessary. Subject would have an AddComment(CommentAR) method to tie the two together. You would probably have a Subject.DeleteComment(CommentVO) unless there’s some sort of delete logic necessary.

  • Thanks Brad for this elaborate answer. To my understanding your approach would require a user to create a comment first and then add that to the subject? Would you consider Comment to be an entity? It relies on the user and the subject to be identifiable. – Pepster Dec 14 '18 at 9:27
  • "Having your Subject own a list of CommentVOs allows it to manage its sub entities as necessary, and your object graph doesn't get dangerously tall." would the subject post or picture not grow a possible indefinite list of CommentVO's that way? – Pepster Dec 14 '18 at 11:09
  • @Pepster That's absolute right. More so than the performance considerations of this implementation is the idea that we need to let the behavior of your system inform the design. If your Subject has no invariant necessitating that it hold a reference to its list of Comment then doing so actually obfuscates your system! Ironically, I think I would suggest that this may be confusing your DB model with your Domain Model. – king-side-slide Dec 14 '18 at 16:13
  • Not sure what db model, I have to decide yet what db to use. Whatever db it will be, a trx boundary that involves applying all comments on load will not work. Maybe the question is more about whether a comment is something that lives on its own or that it is something that is controlled and owned by the subjects. – Pepster Dec 14 '18 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.