Standard value types as ValueObjects in DDD?
Asked Answered
F

2

5

When modeling a domain with entities and value objects, would it make any sense to also make "basic" value types as well defined value objects?

For instance, I can have a value object EmailAddress or ProductName. But what about just String as a value object? Is it against any known principle for any good reason? What I really is wondering is if I should/could define all possible property values as value objects, including string, bool, int etc. Is that wrong or just doing it to far? Somehow I feel I would prefer really being explicit with any "thing" that is a value of some sort and not leave anything open to interpretation. What do you think? What does the gurus say about this?


A reference I stumbled on:

It's often a good idea to replace common primitives, such as strings, with appropriate value objects. While I can represent a telephone number as a string, turning into a telephone number object makes variables and parameters more explicit (with type checking when the language supports it), a natural focus for validation, and avoiding inapplicable behaviors (such as doing arithmetic on integer id numbers).

Farly answered 27/3, 2018 at 10:6 Comment(0)
W
10

Value objects in DDD are a great thing, they are immutable so they are safe for passing around, they encompass the data and its behaviour in a nice OOP mode (if you use OOP). They also make the implicit explicit and provide strong typing.

If you need any of the above features then you should create a Value object (class, component... whatever exist in your language) for any property that needs it.

If however, you don't need any of the above then you should not do it. You don't create a new Class only because some "guru" says so, for example that every property of an Aggregate should be a Value object.

The most important aspect, is that if you have some property that has data and also behavior and you need to make a Class for it then that class should be a Value object, in special, it should be immutable (Entities excluded).

Windproof answered 27/3, 2018 at 10:37 Comment(10)
But if I then have a property in my domain of type "System.UInt64". What would a domain expert think of that? Should he know what that is?. And what does this UInt64-thing translate to in for instance javascript or any other environment than .NET? I mean is that a proper domain model any time? Or am I just nit-picking?Farly
"What would a domain expert think of that? " - if you don't have behavior attached then the domain expert doesn't care about itWindproof
". And what does this UInt64-thing translate to in for instance javascript or any other environment than .NET?" - this transformation is an Infrastructure concern, not Domain. You can create some smart-enough language translators.Windproof
" I mean is that a proper domain model any time?" - you don't create something just because you may need it. YAGNI. If you will need then it you can refactor.Windproof
In the case with UInt64, isn't an implicit behavior at least that the value probably should be greater than 0? Isn't the domain expert interested in that?Farly
If you have behavior then you make a Value object, as I wrote in my answer.Windproof
But still, I have trouble understanding when a value does not have any behavior?Farly
if your value object will have one property and no other methods other than a simple constructor and a method returning that property that means it doesn't have any behavior and it is useless to create that value object. If you can fit some methods inside the value object, that means it has a behavior.Gulf
I argue that constraints on values also motivates having explicit value types (not only behavior). A value without constraint is any value. Also, if a value type have public properties, then they should also be of explicit value object types.Farly
@AndreasZita Behaviours are methods that operate on that data, including validators; builtin converters from one unit to other (from meters to inches), comparators etc; getters are not behaviors.Windproof
D
4

You probably need to read the "Out of the tar pit" whitepaper or watch the talk by Romeu Moura at DDD Norway meetup.

Primitive types are not helping to make implicit explicit. They are implicit by default. This makes the system indefinitely complex since the number of states of such system is indefinite.

I agree that classes might feel like a burden. You might indeed avoid using value objects but then you need to accept that your Ubiquitous Language is not ubiquitous anymore. Ubiquitous means that the language is used everywhere, including the code. You cannot say "product name" to the domain expect and then get back to your code and see "string". This does not convey your domain language to other developers too.

Yves Reinhout delivered the great talk about these things at last year's KanDDDinsly conference, recommended to watch.

I personally really expect new OO language features like the proposed C# record types, to make things just as easy as in functional languages. By the way, reading about type system in functional language provides many great insights for OO programmers too. For example, F# for Fun and Profit has this great article about types and DDD. By the way, it starts by looking string, what a coincidence...

Denti answered 27/3, 2018 at 20:56 Comment(1)
Thanks for the links!Farly

© 2022 - 2024 — McMap. All rights reserved.