Elf*_*lfy 12 php class immutability
创建无法在PHP中更改的对象是一个好主意吗?
例如,具有setter方法的日期对象,但它们将始终返回对象的新实例(具有修改日期).
这些对象是否会让使用该类的其他人感到困惑,因为在PHP中,您通常希望对象发生变化?
例
$obj = new Object(2);
$x = $obj->add(5); // 7
$y = $obj->add(2); // 4
Run Code Online (Sandbox Code Playgroud)
Thi*_*ter 24
不可变对象没有setter方法.期.
每个人都期望一个setXyz()方法具有void返回类型(或者在松散类型的语言中不返回任何内容).如果你确实为你的不可变对象添加了setter方法,那么它会让人感到困惑并导致丑陋的bug.
Thé*_*héo 11
在我看来,对象应该是值对象的不可变对象.除此之外,除非您在整个应用程序中共享对象,否则它没有太大的好处.
这里有一些错误的答案,一个不可变的对象可以有setter.这是PHP中不可变对象的一些实现.
示例#1.
class ImmutableValueObject
{
private $val1;
private $val2;
public function __construct($val1, $val2)
{
$this->val1 = $val1;
$this->val2 = $val2;
}
public function getVal1()
{
return $this->val1;
}
public function getVal2()
{
return $this->val2;
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所见,一旦实例化,您就无法更改任何值.
例2:用setters:
class ImmutableValueObject
{
private $val1;
private $val2;
public function __construct($val1, $val2)
{
$this->val1 = $val1;
$this->val2 = $val2;
}
public function getVal1()
{
return $this->val1;
}
public function withVal1($val1)
{
$copy = clone $this;
$copy->val1 = $val1;
return $copy; // here's the trick: you return a new instance!
}
public function getVal2()
{
return $this->val2;
}
public function withVal2($val2)
{
$copy = clone $this;
$copy->val2 = $val2;
return $copy;
}
}
Run Code Online (Sandbox Code Playgroud)
有几种实现可能,这绝不是排他性列表.请记住,使用Reflection总有一种方法可以在PHP中解决这个问题,所以最终你的不变性就在你的脑海中!
将不可变对象作为最终对象通常也是一种好习惯.
编辑:
不可变对象在初始创建后不能更改,因此使用setter方法没有意义,因为它违背了基本原则.
您可以通过操纵类成员可见性并覆盖magic __set()方法来实现一些变通方法来模拟PHP中的不变性,但不能保证不可变,因为不变性不是语言的一个特性.我相信有人曾经写过一个扩展来在PHP中提供一个不可变的值类型,所以你可以谷歌为此.