Php,如何实现一个完全不可变的构建器类


正如我所看到的,不变性和构建器模式是矛盾的。你不可能同时实现同样的目标。
final class Builder
{
private array $data = [];
public function setName(string $v) : self
{
$this->data['name'] = $v;
return $this;
}
public function setId(int $v) : self
{
$this->data['id'] = $v;
return $this;
}
public function toArray() : array
{
return $this->data;
}
}
$builder = new Builder();
$builder->setName('test')->setId(3);

这很简单,但违反了不变性:$this->data更改两次。当然,还有一个小的变通办法,闻起来像";木制铁环":

final class Builder
{
readonly private string $name;
readonly private int $id;
public function setName(string $v) : self
{
$this->name = $v;
return $this;
}
public function setId(int $v) : self
{
$this->id = $v;
return $this;
}
public function toArray() : array
{
return ['name' => $name, 'id' => $id];
}
}
$builder = new Builder();
$builder->setName('test')->setId(5);

这在理论上实现了不变性,但仍然很臭。定义:;

不可变类定义的对象一旦创建就永远不会改变他们的价值

"但这并不确切地适用于这里。创建Builder后,值在构造后发生更改。当然,最终解决方案:

final class Builder
{
readonly private string $name;
readonly private int $id;
public function __construct(string $name, int $id)
{
$this->name = $name;
$this->id = $v;
}
public function toArray() : array
{
return ['name' => $name, 'id' => $id];
}
}

但这就是为什么使用CCD_ 3来代替此。如果有10个参数呢?什么不是全部是必需的?无论如何,在这种情况下,有必要拥有不可变的类吗?不会使用Builder对象本身,只使用其->toArray()结果!

这听起来都是非常理论化的,实际上并没有考虑为什么会产生这些理论概念。我们为什么要使用不可变对象?

我可以列举几个优点:

  • 它们更高效,因为它们只是存在的,不需要进行任何计算
  • 由于它们不会更改,因此可以在程序的不同部分之间共享,而无需检查其内容
  • 它们无法改变,如果没有适当的检查,这可能总是一个安全风险
  • 它们通常非常简单易懂,这就是编程的主要内容

但是,对象不一定是不可变的。对象通常是可变的,这很好。如果没有可变对象,您的程序将无法执行任何操作。

不要为这些理论概念而烦恼。它们的存在是为了帮助你了解自己在做什么以及后果,但它们并不是铁律。只要你知道自己在做什么,你就可以打破它们,忽略它们。

最新更新