Reputation: 122042
I am just starting out with the study of domain driven design and it is quite possible that my understanding of the Entities/Values divide is faulty so if this is so please let me know.
From my understanding, since its identity is completely defined by its properties an Address is the quintessential value object. From my understanding, this means among other things that there should not be a separate repository or data-access object for addresses.
This creates a dilemma for me since in my case an Address contains a Country where a Country has a name and a country-code and the list of country-codes is supposed to be loaded in from the database.
My question is, how do I design this? I want people to be able to create an address using the new operator but I don't want to create a data access object for country and if I do I certainly don't want to put a reference to it in the address object.
I have some ideas but I'd like to hear any suggestions anyone might have.
Upvotes: 5
Views: 700
Reputation: 1500
Going DDD way, you would think about your application’s needs first, and build model from there.
You shouldn’t worry about Country being used only in Address. It does not make it wrong to make it an Entity per se. The main question is: do you think of a Country as of something having an identity, or is it defined by attributes only? If you have two countries having the same name (and the same country code), can you see any difference?
Maybe you should consider making Country a value object. It does not prevent you from having some repository loading list of countries from DB, or loading Country based on its code. On implementation side, your repository can still load list of countries from database once and cache it in memory. Or it could have it hardcoded, or read from XML. Your domain model would not care.
You will probably create a factory method on Address that accepts country code among other parameters. Then it would use repository to create a Country instance and return a correct Address object.
Thinking about aggregates can also produce some ideas about repository layout.
Hope this helps
Upvotes: 1
Reputation: 542
there is nothing in DDD precluding value objects from holding references to entities. Therefore your address would have a reference to a country entity.
Upvotes: 3
Reputation: 119096
Let me start by saying that my only experience with domain driven design was reading the Wikipedia article a few minutes ago. That being said, here are my thoughts on your question:
I agree that the address object should not require any data-access objects, so how about an address factory which handles the country codes and builds address objects based on inputs from the user? This way, the factory would hold the data access objects, and your address object could remain value-only.
If this isn't kosher according to DDD, then please let me know. I'm curious to see what the rest of the community comes up with.
Upvotes: 1
Reputation: 6756
This creates a dilemma for me since in my case an Address contains a Country where a Country has a name and a country-code and the list of country-codes is supposed to be loaded in from the database.
The Address object would not have a list of countries as its property. Rather, it would have a single instance of the country object. The Presentation Layer would provide a list of Country objects, probably residing in a drop down list. Upon loading one specific address, you would set the value of the drop down list equal to the country ID of the country object which is a property of the Address object. In other words:
myDropDown's (containing a list of Country objects) selected object value = address.Country or myDropDown's key value = address.Country.ID
Now, to populate the Presentation layer, your Data Access Layer should provide a function that returns a raw list of Country objects. In a .NET way, it would be something like:
Namespace Dal
Public NotInheritable Class Countries
...
Public Shared Function Read(ByVal countryId as Integer) As BusinessObjects.Country
...
Public Shared Function ReadList() As List(Of BusinessObjects.Country)
...
Upvotes: 0