Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choosing between immutable objects and structs for value objects

How do you choose between implementing a value object (the canonical example being an address) as an immutable object or a struct?

Are there performance, semantic or any other benefits of choosing one over the other?

like image 370
Garry Shutler Avatar asked Feb 22 '09 22:02

Garry Shutler


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.

Should structs be immutable?

structs are not inherently immutable, that's usually a design goal while using them, though. This SO post should have all you need. Not all reference types are mutable. In fact, some may not have any state whatsoever (such as strategy classes that implement a particular interface, like IComparer<T> ).

Can value object contain Entity?

Yes it can. This would be a relatively obscure case but DDD allows for it and it can be useful. From the DDD book by Eric Evans: VALUE OBJECTS can even reference ENTITIES.

Can we have more than one value object of the same type in a single Entity?

Firstly, when you have two Entities with the same attributes, these two objects are not the same because they have two different identities. However, when you have two Value Objects with the same values, these two objects do have equality and can therefore can be interchanged freely.


2 Answers

There are a few things to consider:

A struct is allocated on the stack (usually). It is a value type, so passing the data around across methods can be costly if it is too large.

A class is allocated on the heap. It is a reference type, so passing the object around through methods is not as costly.

Generally, I use structs for immutable objects that are not very large. I only use them when there is a limited amount of data being held in them or I want immutability. An example is the DateTime struct. I like to think that if my object is not as lightweight as something like a DateTime, it is probably not worth being used as a struct. Also, if my object makes no sense being passed around as a value type (also like DateTime), then it may not be useful to use as a struct. Immutability is key here though. Also, I want to stress that structs are not immutable by default. You have to make them immutable by design.

In 99% of situations I encounter, a class is the proper thing to use. I find myself not needing immutable classes very often. It's more natural for me to think of classes as mutable in most cases.

like image 156
Dan Herbert Avatar answered Oct 19 '22 02:10

Dan Herbert


How do you choose between implementing a value object (the canonical example being an address) as an immutable object or a struct?

I think your options are wrong. Immutable object and struct are not opposites, nor are they the only options. Rather, you've got four options:

  • Class
    • mutable
    • immutable
  • Struct
    • mutable
    • immutable

I argue that in .NET, the default choice should be a mutable class to represent logic and an immutable class to represent an entity. I actually tend to choose immutable classes even for logic implementations, if at all feasible. Structs should be reserved for small types that emulate value semantics, e.g. a custom Date type, a Complex number type similar entities. The emphasis here is on small since you don't want to copy large blobs of data, and indirection through references is actually cheap (so we don't gain much by using structs). I tend to make structs always immutable (I can't think of a single exception at the moment). Since this best fits the semantics of the intrinsic value types I find it a good rule to follow.

like image 14
Konrad Rudolph Avatar answered Oct 19 '22 02:10

Konrad Rudolph