Reputation: 139
I just have started to learn DDD. So I apologise for silly question...
So I have the Post
entity. It looks fine. But it should have tags
.
In code it looks like this (ruby code):
class Post
attr_reader :tags
attr_reader :title
attr_reader :text
# ...
end
class Tag
attr_reader :name
attr_reader :description
# ...
end
Tags aren't make a sense as entity. I don't need tag
itself.
But how should I to implement repository for post?
I have found 2 variants:
1. Build tags in same repository. Like this:
# PostRepository
def find(id)
# getting post data from storage here
# getting tags data
Post.new(title, text, tags_data.map { |tag_data| Tag.new(tag_data[:name], tag_data[:description]))
end
But it looks ugly. Can't clearly say why.
2. Make separate repository for tags.
# PostRepository
def find(id)
# getting post data from storage here
Post.new(title, text, tag_repository.find(tag_ids)) # or tag_names or tag_something
end
Looks better. But is it fine to make separate repository for value-objects?
What is the right way according DDD?
UPD: In other hand, I have to get all available tags. And I never have to change tag with posts. And tags' name looks like identity. Maybe I'm fundamentally wrong? Maybe tag is entity?
UPD2:
This problem shows me that my design skill is very poor. Because of it, there is two question in my one. They are:
But this conditions is result of poor analize. If I could look wider, I would see that tag has it's own life cycle. Though, in context of post, tags are immutable.
Upvotes: 1
Views: 543
Reputation: 771
Tag is most probably just a regular value object in your domain. Tag could be an entity, if it had its own lifecycle. Frankly, I don't think that's the case in your domain, as you can replace each tag with another copy with the same properties.
You can add methods to query tags to your domain repository. It's not a violation of DDD aggregate rules. Aggregates are really about consistency - your repositories should not return parts of your aggregate if you can modify them outside of aggregate context. However, you can explicitly return value objects of your aggregates just for read purposes (e.g. collecting all tags of all posts within selected date range). Besides that, query methods should be placed inside repository for the sake of efficiency. That being said, in your case probably the best solution is to use separate read model (using e.g. nosql db) following CQRS principles. This way you have the model explicitly adjusted to your query needs, so it can very efficient.
Upvotes: 2