Question

I've been reading up a lot on Domain-Driven Development, and I came to the question of how to preserve lack of distinct identity with value objects (VOs). While in the DDD world, this is a requirement (yet I'm not sure I understand the full power of this) it poses problems for the lower ORM layers in terms of persistence.

Tables, for the most part, like to be normalized. It makes life easy in terms of having no delete or insertion anomalies. My concern comes when implementing VOs; they do have primary keys - identities by definition (and foreign keys to their parent). Making them entities is violating DDD in favor of persistence. Instead, I could make a wrapper class that accepts a "bag" of parameters, and then attaches them to each parent's foreign key. While mechanically messy, it sounds like it will work.

I've read a lot of responses on the internet (Stack Overflow also) about denormalizing tables. This concerns me, as now we're violating persistence for DDD.

How to allow VOs to exist by their proper definition without a denormalization?

Was it helpful?

Solution

I really don't think there is problem of VOs having an identity in database, as long as this identity remains hidden and transparent in domain layer itself. I would be data layer's responsibility to keep track of those identities so the domain doesn't have to care about it.

But VOs still give you ability to denormalize. Denormalization can have it's advantages, usually for performance reasons. So you can use this to your advantage.

OTHER TIPS

This is an issue if you use an ORM to map your domain objects directly to the DB. This falls apart rather quickly for all but the most trivial of applications. Instead create separate classes to represent your data store and map those. You will need code that maps the BOs to the DTOs, but you will not be forced to compromise your domain classes to make the ORM happy, which is invariably what happens. You will also avoid the leaky abstraction that comes with using a ORM.

Given the above, how you persist value objects depends. If you're storing for example geo coordinates, I probably wouldn't normalize these and store them in the same table as the entity. If your value types really do have their own identity though, that suggests to me that they probably shouldn't be value objects in your domain layer. That's really the defining difference between a value object and entity in DDD. I always like to go to the source for DDD; unfortunately many of the blogs you'll see on the internet (especially those that really like NHibernate) don't really get DDD right at all, and following their advise usually leads you to the anemic domain model anti-pattern.

Database identity and domain identity are not same things, on db level you are allowed to do whatever optimization you need and in domain layer you decide (business requirements) how would you handle your models - as entities or value objects.

In relational db's I like to put unique constraint on fields that compose my value object just to be sure to keep value object safe, if there are some foreign keys - all fine.

The main property of Value Objects (i.e. values) beside that they are immutable is that they are exchangeable.

So if I set a value to "3", it doesn't make any difference at all to set it to a "different" "3". 3 is just 3, it's a value.

It doesn't really make any difference how you persist it, the important part is that these properties hold. The question is: do they? If your value has a reference to its "parent", or even an Id, can I really exchange that value to another equal value? I guess it might be possible, but it seems sketchy.

Licensed under: CC-BY-SA with attribution
scroll top