views:

222

answers:

4

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.

A: 

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)
    ...
HardCode
I am designing the domain model only, not mandating how it will be used. The problem is that then users can create new Country objects, but if they do then how do I ensure that its in a valid state?
George Mauer
This approach is making too much assumptions. I cannot assume that there will be a presentation layer that has access to thee country list. Also like I said a Data Access Object for a value object just seems wrong...
George Mauer
+1  A: 

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.

e.James
Not sure how this meshes for DDD, I think its fine. This is similar to what I'm thinking, though I just had the Address class managing this from a static Country list that gets set at the application start. I think I like yours better.
George Mauer
+1  A: 

there is nothing in DDD precluding value objects from holding references to entities. Therefore your address would have a reference to a country entity.

Simon Laroche
Perhaps, but given that within my domain it is only used in addresses, it seems wrong to make Country an entity
George Mauer
Plus I don't know how to implement that. If I'm allowing people to new up Address objects then the address object would need a reference to an implementation of the country DAO which breaks some serious DI principles
George Mauer
Why would the address need to know abouot a DAO thingy. Just have a country property and let the clients deal with having to find a country. When using hibernate as a repository/DAO this kind of stuff is trivial since it will make sure you get a country when address is loaded from the database.
Simon Laroche
+1  A: 

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

Alexander Abramov
This does, thank you very much. Its along the lines of what I was thinking. Do you think addresses be new-able or only created via an AddressFactory that contains a list of countries?
George Mauer
Well, Eric Evans likes to see his constructors very simple. In this case country lookup is probably a job for factory method, not for constructor. I don't have a strong opinion about this yet.
Alexander Abramov