Consider the typical blog with objects Post
and Comment
.
For a DDD demo example i have been building i have (till now) found that both the entities Post
and Comment
have been appropriate for the same aggregate- the Post
aggregate. But now i'm not so sure..
In my controllers i am finding, like you would expect, that i need to add and remove Comments
from Posts
. With my current model i am not tracking the identity of a Comment
globally (like the Blue Book suggests). You you might expect that my action to delete a Comment
may look like this:
public ActionResult DeleteComment(int postID, int commentID)
Obviously i need the Post
's id to retrieve it from the repository and the identifier for the particular Comment
on that Post
that i want to delete.
My problem is the body of the DeleteComment(
action:
Is it ok to traverse the Post
with a query mechanism to get the Comment
for deletion? like this:
var comment = this._postRepo.WithID(postID).Comments
.SingleOrDefault(c => c.ID == commentID);
this._postRepo.Delete(comment);
return RedirectToAction("detail", new { id = postID });
..or should i be selecting the Comment
from the repo similar to this?:
var comment = this._postRepo.CommentWithID(commentID)
..or:
var comment = this._postRepo.CommentWithID(postID, commentID)
The two above examples might seem a little silly since i shouldn't need the Post
ID if i can track the Comment
globally. But then if i'm tracking the Comment
globally, shouldn't it have it's own aggregate and then is that right when Post
and Comment
seem to go together?
In DDD you can reference an aggregate root from another aggregate. What you cannot do is reference anything inside the other aggregate root.
Aggregates are a design pattern that play a big role in domain-driven development. In many systems, the relationships between entities can become so interwoven that attempting to eager-load an entity and all of its related entities from persistence results in attempting to download the entire database.
Aggregation is the boundary of consistency and the encapsulation of closely related objects. Aggregation encapsulates entity objects and value objects and takes the most important entity object as the aggregate root.
One good way of identifying the aggregate root is to use the "delete" test. In your domain if you delete the root, what is deleted with it? This way you can identify domain object ownership, which is a trait of Aggregates.
As others have said, it depends greatly on whether a comment has any meaning outside of a Post. I tend to think that it does, for several reasons. First, things other than posts can conceptually be commented upon in a normal blog engine (e.g. an image, a news item, another comment). Second, as was also brought up, you often see widgets of just comments, which are independent of their posts. I also think that this scenario makes the decisions you're agonizing over a bit more trivial.
That said, if you do choose to make them one aggregate, then remember that a repository will often load the entire aggregate when making queries, relying on mechanisms like caching and such to make that efficient. So your scenario would be a query for a post, followed by a search of that post's comments for the 'right' comment to edit/delete/whatever.
In my opinion , comment should be part of Post Aggregate, but comment should be entity, bcoz two comment with the same answer is still two separate comment.
If you create comment as separate aggregate where comment is root then, comment will have store method that means any body can create comment but the basic idea is comment should not be created without its post.Comment is related with post.
If you think logically , Comment cannot be evolve it's own. That means when commented is created it should be part of post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With