In php in this example – but in general programming actually, is there a way distinguish between a "no-assignment" and "unset-value" command for null
values when merging 2 immutable data objects of the same type?
Consider this php class that is an immutable data object. It takes a string and an integer in its constructor, and only provides accessors for the values:
class Data
{
protected $someNumber;
protected $someString;
public function __construct(?int $someNumber, ?string $someString)
{
$this->someNumber = $someNumber;
$this->someString = $someString;
}
public function getSomeNumber(): ?int
{
return $this->someNumber;
}
public function getSomeString(): ?string
{
return $this->someString;
}
}
The values can be either null
or their respective datatypes string
or integer
at all times. Also the constructor accepts null
values instead of string
and / or int
: the UNSET operation.
Now I want to be able to merge 2 instances of Data
, something like this simplified factory method that accepts $first
and $second
, where data in $second
overrides data in $first
, if present.
class DataFactory
{
public function merge(Data $first, Data $second): Data
{
$firstNumber = $first->getSomeNumber();
$firstString = $first->getSomeString();
$secondNumber = $second->getSomeNumber();
$secondString = $second->getSomeString();
// This must be this strict.
$newNumber = null === $secondNumber ? $firstNumber : $secondNumber;
$newString = null === $secondString ? $firstString : $secondString;
return new Data($newNumber, $newString);
}
}
In the above example, null
values returned by the accessors of $second
are interpreted as NO UPDATE operation: when null
is encountered the corresponding value of $first
is kept. The problem is that I want to be able to distinguish between a request for either a NO UPDATE operation or an UNSET operation within merge
.
The strict typing in the classes disallows the use of some sort of string constant like "DATA_UNSET_FIELD"
as a value to flag, so implementing this directly on the data itself seems impossible. More so even because passing it null should definitely mean UNSET.
I am thinking about some sort of update lens that explicitly specifies the properties that should be UNSET, so that null
values in $second
would simply mean NO UPDATE.
What would be a compact object oriented pattern to solve this? I can already imagine problems like exploding plain array schemas or a class explosion of strategy classes as data grows. Also I'm slightly concerned about the "mobility" of Data
objects as new objects have to be associated with them at some point.
Thanks in advance!
This is an actual problem I'm facing in a live project :)
Aucun commentaire:
Enregistrer un commentaire