I don't get why value objects in DDD should be immutable, nor do I see how this is easily done. (I'm focusing on C# and Entity Framework, if that matters.)
For example, let's consider the classic Address value object. If you needed to change "123 Main St" to "123 Main Street", why should I need to construct a whole new object instead of saying myCustomer.Address.AddressLine1 = "123 Main Street"? (Even if Entity Framework supported structs, this would still be a problem, wouldn't it?)
I understand (I think) the idea that value objects don't have an identity and are part of a domain object, but can someone explain why immutability is a Good Thing?
EDIT: My final question here really should be "Can someone explain why immutability is a Good Thing as applied to Value Objects?" Sorry for the confusion!
EDIT: To clairfy, I am not asking about CLR value types (vs reference types). I'm asking about the higher level DDD concept of Value Objects.
For example, here is a hack-ish way to implement immutable value types for Entity Framework: http://rogeralsing.com/2009/05/21/entity-framework-4-immutable-value-objects. Basically, he just makes all setters private. Why go through the trouble of doing this?
Value objects should be immutable: this is required for the implicit contract that two value objects created equal, should remain equal. It is also useful for value objects to be immutable, as client code cannot put the value object in an invalid state or introduce buggy behaviour after instantiation.
The main difference between entities and value objects lies in the way we compare their instances to each other. The concept of identifier equality refers to entities, whereas the concept of structural equality - to value objects. In other words, entities possess inherent identity while value objects don't.
Value Object is an object that represents a concept from your problem Domain. It is important in DDD that Value Objects support and enrich Ubiquitous Language of your Domain. They are not just primitives that represent some values - they are domain citizens that model behaviour of your application.
Value Objects can be especially useful as a means for describing concepts in an application that have intrinsic rules but which are not themselves entities. In many applications, some concepts that are described as entities would be better off implemented as value objects.
Ignore all the crazy answers about thread safe etc, that has nothing to do with DDD. (I've yet to see a thread safe O/R mapper or other DDD friendly dal)
Imagine a value object for weights. lets say we have a KG value object.
sample (edited for clarity):
var kg75 = new Weight(75); joe.Weight = kg75; jimmy.Weight = kg75;
Now what would happen if we do:
jimmy.Weight.Value = 82;
That would change the weight of joe too, if we are still using the same object references that is. Note that we assigned an object representing 75kg to both joe and jimmy. When jimmy gains weight, it is not the kg75 object that has changed, it is jimmys weight that has changed, thus, we should create a new object representing 82 kg.
But what if we have a new session and load both joe and jimmy in a clean UoW?
var joe = context.People.Where(p => p.Name = "joe").First(); var jimmy = context.People.Where(p => p.Name = "jimmy").First(); jimmy.Weight.Value = 82;
What would happen then? well, since EF4 in your case would load joe and jimmy and their weights without any identity , we would get two different weight objects and when we change jimmys weight , joe would still weigh the same as before.
So we would have two different behaviours for the same code. If the object references are still the same, then both joe and jimmy would get a new weight. If joe and jimmy are loaded in a clean uow, only one of them would be affected by the change.
And that would be quite incosistent imo.
By using immutable VO's, you would get the same behavior in both cases and you can still reuse object references for a smaller memory footprint when constructing object graphs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With