I need some help...
Value objects, by definition, are immutable data classes that only use other value objects or primitives. And an value object only should be created with a valid value.
But... what happens when to construct a valid value object we need to validate the data using a third party library?
For example a Phone and a Mobile value objects. Build a valid phone depends on a country and the validation rules could constantly change and be complex. We don't want to spend time changing phone validation rules because this is not the core of the our business... so we want to validate the data using Google libphone library.
Possible solutions:
new Phone($phone, $validator)
Phone::fromString($phone, $validator)
First and second options I guess is not the correct way, Value objects don't necessarily need collaborators...
Third option allows to create invalid phones if you instantiate the phone outside the factory.
Any idea?
Thanks.
The solution for this is to have 2 types UnvalidatedPhone
and ValidatedPhone
(both part of the domain), together with your 3rd option.
The incoming command will have an UnvalidatedPhone
and as you process the command, at some point you'll validate it using the builder/factory and get a ValidatedPhone
. This is even better if you can hide the constructor of ValidatedPhone
, so the validator is the only thing that can create a ValidatedPhone
.
Mini warning: If you are writing this in an OO language (I guess you do), the two phone classes don't need to be part of a hierarchy. Try to keep them separate.