8

Lets suppose there's a database schema defined like this:

Person.mail_address_key ----- Address.address_key
Person.billing_address_key ----- Address.address_key

A Person has a mailing address and a billing address. As a denormalization technique, we create a separate Address table. Most of the time the mail_address_key and the billing_address_key of a single Person will be the same value (ie: their mailing and billing address key will be the same).

In my database the Address has an identity (the address key). But, in my domain model, I don't see a compelling reason for the Address to be an Entity, I'd like it to be a Value Object.

  1. In DDD, is this an option? Or are Value Objects usually a group of columns (as opposed to a table)? I'm kind of playing the devil's advocate here, because I don't think the database should dictate the domain model structure, but just making sure.
  2. If so, where/when/how does the address lose its database identity so it can be used as a Value Object in the Domain Layer? Or, am I supposed to keep the database identifier in the Value Object?
  3. When the model needs to be persisted in the database, what's the process? Am I supposed to go through a process of a) Find an address by these fields, b) if it doesn't exist, create a new one c) if it does, update the fields?
  • Making an email address a useable value object can be very difficult, because testing email addresses for equality is not that easy and probably testing postal addresses isn't either. – SpaceTrucker Oct 8 '14 at 8:55
  • @SpaceTrucker I don't think I've read anything that says that should factor into your decision of making a model a Value Object. – Daniel Kaplan Oct 8 '14 at 15:13
2

In DDD, is this an option? Or are Value Objects usually a group of columns (as opposed to a table)? I'm kind of playing the devil's advocate here, because I don't think the database should dictate the domain model structure, but just making sure.

The database should not dictate the domain model structure so you're correct on that. Value objects can be stored in the database as either a column or table depending on the type of data the value object is supposed to carry.

If so, where/when/how does the address lose its database identity so it can be used as a Value Object in the Domain Layer? Or, am I supposed to keep the database identifier in the Value Object?

Your domain code should not be riddled with properties that are for other concerns like persistence since they should be completely persistence ignorant. You should really focus on your aggregate root. You must have some way of identifying your aggregate root when you save it back to the database so, at that point, you would just need to check the Person table record (I'm assuming Person is your aggregate root) and see if there is a value in the MailingAddressID or BillingAddressID field. At that point, you can decide whether to create new addresses and change the links to point to the new addresses or overwrite the addresses that are already linked.

When the model needs to be persisted in the database, what's the process? Am I supposed to go through a process of a) Find an address by these fields, b) if it doesn't exist, create a new one c) if it does, update the fields?

As I somewhat explained in the above answer, you should hydrate and de-hydrate your object graph based on your aggregate root. Therefore, when your repository gets your aggregate root from the database, it will also hydrate all of the necessary entities and value objects under your aggregate root that are associated with your aggregate root in the database. The same is true when you go to save the aggregate root back to the database. Your repository should be able to handle your entire object graph under the aggregate root.

  • Ah, that makes a lot of sense. Thanks for the help. – Daniel Kaplan Nov 1 '14 at 11:23
2

DDD does not enforce DB schema at all. The value object may be implemented as a group of columns, db entity (your third solution) or simply in a denormalized form if you can use document-oriented database for instance. It depends on different circumstances what is the best option to go with.

Keep in mind that DB is only a tool for persisting your domain state. It should not force any design decision. If for some reason you have to use identity for your value object's representation in DB, do so, but do not leak this implementation detail into the domain itself. Create a wrapper/extend domain classes/whatever your framework allows and add the ID in completely separate, infrastructural class enabling the application/framework to persist the state.

  • Can you show some concrete implementations (can be pseudo code)? – Daniel Kaplan Oct 7 '14 at 23:23
-1

I don't see any DDD's special requirements in this case, you can model mailing and billing addresses as person's properties and still store them in a separate table, for example:

Person
+ MailingAddress : Address
+ BillingAddress : Address

or

Person
+ MailingAddressID
+ MailingAddress : Address
+ BillingAddressID
+ BillingAddress : Address
  • 1
    I don't feel like this is answering all (or even a majority) of my questions – Daniel Kaplan Oct 8 '14 at 5:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.