DDD – How to Refer to Value Object Inside Aggregate

Architecturedomain-driven-design

We have an aggregate of:

  • entity: Poll (representing a question)
  • two or more value objects Choice

Adding choices is done through Poll, repository stores only the aggregate, i.e. everything is done as expected.

Now, I need to select specific Choice that user chose. From the UI I will have only the choiceId of selected choice. So would my Poll.voteForChoice() method be:

  • voteForChoice(choiceId) – where I pass the choice id to the aggregate root, so he iterates it's choices and finds the target choice so to increment the count. However, we are using ID here for the choice, and choice is value object.
  • voteForChoice(Choice) – where we are sending the full value object, meaning I need to create it first before I do the voting. That also means I will need to have a Repo for choices, and they are value objects, so that clashes with all what I've learned 😉
  • or it should be: Poll.getChoice(choiceId).vote().
  • or the Choice is actually an entity, so we would use Repository to fetch choice: ChoiceRepo.find(id).vote().

Simple case, but what is the correct answer in DDD world?

Best Answer

Depending on the collaborative degree of your application, you might find yourself in trouble if 2 or more users try to increment the same Choice concurrently. That will happen whether it's a VO or an Entity in the same Aggregate as the Poll.

To me the natural consistency boundary implied by the domain action of voting includes the user. So I would suggest a full fledged PollChoice Aggregate Root with a link to the User, or if there are multiple choices per poll, a PollResponse AR containing all choices (which can then be VO's) made by a particular user to a specific poll.

Edit : something along these lines

class PollResponse {

  int pollId;
  int userId;
  Choice choice;
  Datetime dateResponded;
}