Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value objects in DDD - Why immutable?

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?

like image 462
Hobbes Avatar asked Jan 03 '11 01:01

Hobbes


People also ask

Should value objects be immutable?

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.

What is the difference between Entity and value object in DDD?

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.

What is value object in DDD example?

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.

What are value objects used for?

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.


1 Answers

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.

like image 184
Roger Johansson Avatar answered Oct 09 '22 12:10

Roger Johansson