michael-rubel / laravel-value-objects

A bunch of general-purpose value objects you can use in your Laravel application.
MIT License
189 stars 14 forks source link

Values object must be immutable #13

Closed MuntzMathias closed 1 year ago

MuntzMathias commented 1 year ago

According to the principles of DDD, Values object must be immutable, but here the constructor are public. So i can easily do this.

$test = new Text('value1');
$test->__construct('value2');

echo $test->value; // value2

Shouldn't you protect this method, and make it call from a static method like ValueObject::new($value) ?

michael-rubel commented 1 year ago

The objects are immutable, but not in the constructor.

If you try to assign the value manually, it will throw an exception:

$test = new Text('value1');

$test->value = 'new value'; // ... Exception

I've considered making constructors final, but this way developers are limited in extending/overriding the constructor logic, e.g. Name extends Text and adds sanitization logic. With construct being final we'll be unable to do that.

michael-rubel commented 1 year ago

Came up with a non-breaking solution, and also to keep extendability in #14

This will be shipped as a minor release in a while.

MuntzMathias commented 1 year ago

I would have simply put the constructor in protected so that the developers cannot use it without passing a static method which will act as a factory.

protected function __construct(string|Stringable $value)
{
    // ....
}

public static function make(mixed ...$values): static
{
    return new static(...$values);
}