Skip to main content
deleted 249 characters in body
Source Link
zafarkhaja
  • 297
  • 2
  • 4

I believe that a value object should be referred by its value because that's what makes it unique, notneither a GUID. However, this doesn't mean you can't use "local" ID's to differentiate between Choices of nor a Polllocal ID.

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);
 

// 1) you can refer to a choice by its value
poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");
 
// 2) or if the text of a choice is too long
poll1.voteForChoice("B");
poll2.voteForChoice("A");

// 3) you could also use a numeric "local" ID
poll1.voteForChoice(2);
poll2.voteForChoice(1);

I think all of the above are pretty much acceptable and don't violate DDD principles.

pollpoll1.voteForChoice(new Choice("Firefox"));
poll.voteForChoice(new Choice("A"));
pollpoll2.voteForChoice(new Choice(1"Chrome"));

So, with the above caveatsit seems like you can use the first two signaturessecond option for the voteForChoice method whichever suits your model best. The first one uses ID which suggests that Choices be modeled as entities. The third one feels wrong like a leaky abstraction and breach of encapsulation. The forth one is wrong because of using a repository for a value object.

I know I've made it even more confusing for you, but the thing that I want to emphasize is that you have to decide for yourself what kind of domain model you need. My answer was based on the assumption derived from your question that value objects is what you need.


UPDATE 2

It turns out that according to Eric Evans when you tempted to create some sort of identifier for a value object even if it's a local one you should consider making it an entity instead.

I believe that a value object should be referred by its value because that's what makes it unique, not a GUID. However, this doesn't mean you can't use "local" ID's to differentiate between Choices of a Poll.

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);
 

// 1) you can refer to a choice by its value
poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");
 
// 2) or if the text of a choice is too long
poll1.voteForChoice("B");
poll2.voteForChoice("A");

// 3) you could also use a numeric "local" ID
poll1.voteForChoice(2);
poll2.voteForChoice(1);

I think all of the above are pretty much acceptable and don't violate DDD principles.

poll.voteForChoice(new Choice("Firefox"));
poll.voteForChoice(new Choice("A"));
poll.voteForChoice(new Choice(1));

So, with the above caveats you can use the first two signatures for the voteForChoice method whichever suits your model best. The third one feels wrong like a leaky abstraction and breach of encapsulation. The forth one is wrong because of using a repository for a value object.

I know I've made it even more confusing for you, but the thing that I want to emphasize is that you have to decide for yourself what kind of domain model you need. My answer was based on the assumption derived from your question that value objects is what you need.

I believe that a value object should be referred by its value because that's what makes it unique, neither a GUID nor a local ID.

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);

poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");
poll1.voteForChoice(new Choice("Firefox"));
poll2.voteForChoice(new Choice("Chrome"));

So, it seems like you can use the second option for the voteForChoice method. The first one uses ID which suggests that Choices be modeled as entities. The third one feels wrong like a leaky abstraction and breach of encapsulation. The forth one is wrong because of using a repository for a value object.

I know I've made it even more confusing for you, but the thing that I want to emphasize is that you have to decide for yourself what kind of domain model you need. My answer was based on the assumption derived from your question that value objects is what you need.


UPDATE 2

It turns out that according to Eric Evans when you tempted to create some sort of identifier for a value object even if it's a local one you should consider making it an entity instead.

Removed confusing statement
Source Link
zafarkhaja
  • 297
  • 2
  • 4

I believe that a value object should be referred by its value because that's what makes it unique, not a GUID. Making Choice an entity, that's making it globally unique by assigning a GUID to it, doesn't make sense either because it only has meaning in the context of its Poll. However, this doesn't mean you can't use "local" ID's to differentiate between Choices of a Poll.

Consider a real world example

  1. What web browser do you use at work?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari
  1. What web browser do you use at home?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari

How would you vote in the real world? You would probably say something along the lines "For the first poll I vote for 'Firefox'" or "For the second poll I choose 'A'". Hence, there are few ways you can go about modeling the voting behavior

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);


// 1) you can refer to a choice by its value
poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");

// 2) or if the text of a choice is too long
poll1.voteForChoice("B");
poll2.voteForChoice("A");

// 3) you could also use a numeric "local" ID
poll1.voteForChoice(2);
poll2.voteForChoice(1);

I think all of the above are pretty much acceptable and don't violate DDD principles.

On the other hand, there's nothing wrong in creating an instance of a value object outside the scope of its aggregate without using a repository

poll.voteForChoice(new Choice("Firefox"));
poll.voteForChoice(new Choice("A"));
poll.voteForChoice(new Choice(1));

So, with the above caveats you can use the first two signatures for the voteForChoice method whichever suits your model best. The third one feels wrong like a leaky abstraction and breach of encapsulation. The forth one is wrong because of using a repository for a value object.


UPDATE

Important point. There's no a single recipe how to model your domain even if it's a common case in the real world. You may design your Choices as value objects and have a Map<Choice, Counter> choices property in your Polls. Or, you may design it as entities and have the counter as a part of a Choice. Additionally, you might want to have a List<User> users collection in the Choice entity to keep a track of users who voted for a particular Choice.

I know I've made it even more confusing for you, but the thing that I want to emphasize is that you have to decide for yourself what kind of domain model you need. My answer was based on the assumption derived from your question that value objects is what you need.

I believe that a value object should be referred by its value because that's what makes it unique, not a GUID. Making Choice an entity, that's making it globally unique by assigning a GUID to it, doesn't make sense either because it only has meaning in the context of its Poll. However, this doesn't mean you can't use "local" ID's to differentiate between Choices of a Poll.

Consider a real world example

  1. What web browser do you use at work?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari
  1. What web browser do you use at home?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari

How would you vote in the real world? You would probably say something along the lines "For the first poll I vote for 'Firefox'" or "For the second poll I choose 'A'". Hence, there are few ways you can go about modeling the voting behavior

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);


// 1) you can refer to a choice by its value
poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");

// 2) or if the text of a choice is too long
poll1.voteForChoice("B");
poll2.voteForChoice("A");

// 3) you could also use a numeric "local" ID
poll1.voteForChoice(2);
poll2.voteForChoice(1);

I think all of the above are pretty much acceptable and don't violate DDD principles.

On the other hand, there's nothing wrong in creating an instance of a value object outside the scope of its aggregate without using a repository

poll.voteForChoice(new Choice("Firefox"));
poll.voteForChoice(new Choice("A"));
poll.voteForChoice(new Choice(1));

So, with the above caveats you can use the first two signatures for the voteForChoice method whichever suits your model best. The third one feels wrong like a leaky abstraction and breach of encapsulation. The forth one is wrong because of using a repository for a value object.


UPDATE

Important point. There's no a single recipe how to model your domain even if it's a common case in the real world. You may design your Choices as value objects and have a Map<Choice, Counter> choices property in your Polls. Or, you may design it as entities and have the counter as a part of a Choice. Additionally, you might want to have a List<User> users collection in the Choice entity to keep a track of users who voted for a particular Choice.

I know I've made it even more confusing for you, but the thing that I want to emphasize is that you have to decide for yourself what kind of domain model you need. My answer was based on the assumption derived from your question that value objects is what you need.

I believe that a value object should be referred by its value because that's what makes it unique, not a GUID. However, this doesn't mean you can't use "local" ID's to differentiate between Choices of a Poll.

Consider a real world example

  1. What web browser do you use at work?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari
  1. What web browser do you use at home?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari

How would you vote in the real world? You would probably say something along the lines "For the first poll I vote for 'Firefox'" or "For the second poll I choose 'A'". Hence, there are few ways you can go about modeling the voting behavior

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);


// 1) you can refer to a choice by its value
poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");

// 2) or if the text of a choice is too long
poll1.voteForChoice("B");
poll2.voteForChoice("A");

// 3) you could also use a numeric "local" ID
poll1.voteForChoice(2);
poll2.voteForChoice(1);

I think all of the above are pretty much acceptable and don't violate DDD principles.

On the other hand, there's nothing wrong in creating an instance of a value object outside the scope of its aggregate without using a repository

poll.voteForChoice(new Choice("Firefox"));
poll.voteForChoice(new Choice("A"));
poll.voteForChoice(new Choice(1));

So, with the above caveats you can use the first two signatures for the voteForChoice method whichever suits your model best. The third one feels wrong like a leaky abstraction and breach of encapsulation. The forth one is wrong because of using a repository for a value object.


UPDATE

Important point. There's no a single recipe how to model your domain even if it's a common case in the real world. You may design your Choices as value objects and have a Map<Choice, Counter> choices property in your Polls. Or, you may design it as entities and have the counter as a part of a Choice. Additionally, you might want to have a List<User> users collection in the Choice entity to keep a track of users who voted for a particular Choice.

I know I've made it even more confusing for you, but the thing that I want to emphasize is that you have to decide for yourself what kind of domain model you need. My answer was based on the assumption derived from your question that value objects is what you need.

Update from comments
Source Link
zafarkhaja
  • 297
  • 2
  • 4

I believe that a value object should be referred by its value because that's what makes it unique, not a GUID. Making Choice an entity, that's making it globally unique by assigning a GUID to it, doesn't make sense either because it only has meaning in the context of its Poll. However, this doesn't mean you can't use "local" ID's to differentiate between Choices of a Poll.

Consider a real world example

  1. What web browser do you use at work?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari
  1. What web browser do you use at home?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari

How would you vote in the real world? You would probably say something along the lines "For the first poll I vote for 'Firefox'" or "For the second poll I choose 'A'". Hence, there are few ways you can go about modeling the voting behavior

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);


// 1) you can refer to a choice by its value
poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");

// 2) or if the text of a choice is too long
poll1.voteForChoice("B");
poll2.voteForChoice("A");

// 3) you could also use a numeric "local" ID
poll1.voteForChoice(2);
poll2.voteForChoice(1);

I think all of the above are pretty much acceptable and don't violate DDD principles.

On the other hand, there's nothing wrong in creating an instance of a value object outside the scope of its aggregate without using a repository

poll.voteForChoice(new Choice("Firefox"));
poll.voteForChoice(new Choice("A"));
poll.voteForChoice(new Choice(1));

So, with the above caveats you can use the first two signatures for the voteForChoice method whichever suits your model best. The third one feels wrong like a leaky abstraction and breach of encapsulation. The forth one is wrong because of using a repository for a value object.


UPDATE

Important point. There's no a single recipe how to model your domain even if it's a common case in the real world. You may design your Choices as value objects and have a Map<Choice, Counter> choices property in your Polls. Or, you may design it as entities and have the counter as a part of a Choice. Additionally, you might want to have a List<User> users collection in the Choice entity to keep a track of users who voted for a particular Choice.

I know I've made it even more confusing for you, but the thing that I want to emphasize is that you have to decide for yourself what kind of domain model you need. My answer was based on the assumption derived from your question that value objects is what you need.

I believe that a value object should be referred by its value because that's what makes it unique, not a GUID. Making Choice an entity, that's making it globally unique by assigning a GUID to it, doesn't make sense either because it only has meaning in the context of its Poll. However, this doesn't mean you can't use "local" ID's to differentiate between Choices of a Poll.

Consider a real world example

  1. What web browser do you use at work?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari
  1. What web browser do you use at home?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari

How would you vote in the real world? You would probably say something along the lines "For the first poll I vote for 'Firefox'" or "For the second poll I choose 'A'". Hence, there are few ways you can go about modeling the voting behavior

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);


// 1) you can refer to a choice by its value
poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");

// 2) or if the text of a choice is too long
poll1.voteForChoice("B");
poll2.voteForChoice("A");

// 3) you could also use a numeric "local" ID
poll1.voteForChoice(2);
poll2.voteForChoice(1);

I think all of the above are pretty much acceptable and don't violate DDD principles.

On the other hand, there's nothing wrong in creating an instance of a value object outside the scope of its aggregate without using a repository

poll.voteForChoice(new Choice("Firefox"));
poll.voteForChoice(new Choice("A"));
poll.voteForChoice(new Choice(1));

So, with the above caveats you can use the first two signatures for the voteForChoice method whichever suits your model best. The third one feels wrong like a leaky abstraction and breach of encapsulation. The forth one is wrong because of using a repository for a value object.

I believe that a value object should be referred by its value because that's what makes it unique, not a GUID. Making Choice an entity, that's making it globally unique by assigning a GUID to it, doesn't make sense either because it only has meaning in the context of its Poll. However, this doesn't mean you can't use "local" ID's to differentiate between Choices of a Poll.

Consider a real world example

  1. What web browser do you use at work?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari
  1. What web browser do you use at home?
  • A) Chrome
  • B) Firefox
  • C) Internet Explorer
  • D) Opera
  • E) Safari

How would you vote in the real world? You would probably say something along the lines "For the first poll I vote for 'Firefox'" or "For the second poll I choose 'A'". Hence, there are few ways you can go about modeling the voting behavior

// 1st poll (GUID = 1)
Poll poll1 = pollRepo.find(1);

// 2nd poll (GUID = 2)
Poll poll2 = pollRepo.find(2);


// 1) you can refer to a choice by its value
poll1.voteForChoice("Firefox");
poll2.voteForChoice("Chrome");

// 2) or if the text of a choice is too long
poll1.voteForChoice("B");
poll2.voteForChoice("A");

// 3) you could also use a numeric "local" ID
poll1.voteForChoice(2);
poll2.voteForChoice(1);

I think all of the above are pretty much acceptable and don't violate DDD principles.

On the other hand, there's nothing wrong in creating an instance of a value object outside the scope of its aggregate without using a repository

poll.voteForChoice(new Choice("Firefox"));
poll.voteForChoice(new Choice("A"));
poll.voteForChoice(new Choice(1));

So, with the above caveats you can use the first two signatures for the voteForChoice method whichever suits your model best. The third one feels wrong like a leaky abstraction and breach of encapsulation. The forth one is wrong because of using a repository for a value object.


UPDATE

Important point. There's no a single recipe how to model your domain even if it's a common case in the real world. You may design your Choices as value objects and have a Map<Choice, Counter> choices property in your Polls. Or, you may design it as entities and have the counter as a part of a Choice. Additionally, you might want to have a List<User> users collection in the Choice entity to keep a track of users who voted for a particular Choice.

I know I've made it even more confusing for you, but the thing that I want to emphasize is that you have to decide for yourself what kind of domain model you need. My answer was based on the assumption derived from your question that value objects is what you need.

added 26 characters in body
Source Link
zafarkhaja
  • 297
  • 2
  • 4
Loading
deleted 1 character in body
Source Link
zafarkhaja
  • 297
  • 2
  • 4
Loading
Source Link
zafarkhaja
  • 297
  • 2
  • 4
Loading