在本例中的php中,但实际上在一般编程中,是否有方法区分
“无转让”
和
“未设置值”
命令
null
合并同一类型的两个不可变数据对象时的值?
考虑这个php类,它是一个不可变的数据对象。它在构造函数中接受一个字符串和一个整数,并且只为值提供访问器:
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;
}
}
值可以是
无效的
或它们各自的数据类型
string
或
integer
任何时候。构造器也接受
无效的
值而不是
一串
和/或
int
:未设置操作。
现在我希望能够合并
Data
,类似于接受
$first
和
$second
,其中数据位于
$秒
覆盖中的数据
$第一
,如果存在。
class DataFactory
{
public function merge(Data $first, Data $second): Data
{
// Uses data from $first if corresponding data from
// $second is (strictly) null
return new Data(
$second->getSomeNumber() ?? $first->getSomeNumber(),
$second->getSomeString() ?? $first->getSomeString(),
}
}
在上面的例子中,
无效的
的访问器返回的值
$秒
被解释为无更新操作:当
无效的
遇到相应的值
$第一
被保留。问题是,我希望能够区分请求中的无更新操作或未设置操作
merge
.
严格的打字
数据
类不允许使用某种字符串常量,如
"DATA_UNSET_FIELD"
作为一个要标记的值,因此直接在数据本身上实现这一点似乎是不可能的。更甚者,因为为任何值传递构造函数null肯定意味着SET null。
我正在考虑某种类型的更新镜头,它显式地指定合并时应该取消设置的属性,以便
无效的
价值观
$秒
只意味着没有更新
$第一
).
解决这个问题的紧凑的面向对象模式是什么?我已经可以想象一些问题,比如随着数据的增长,展开普通数组模式或策略类的类爆炸。我也有点担心
数据
对象作为新对象必须在某个点与它们关联。
提前谢谢!
编辑
我想能够区分
不重写
当前值和
不稳定
一个值,即赋值
无效的
–当合并2个
数据
,其中
$第一
是基地,而且
$秒
覆盖的数据
$第一
. 作为一个细节,合并会产生第三个新对象,即合并结果。
看着
DataFactory
片段
无效的
价值观
$秒
当前被解释为“保持
$第一
". 但是,如何为每个字段携带另一个标志,指示应将哪些字段设置为
无效的
在生成的对象中,以一种干净的方式,并且不会过多地干扰数据类?