12

我正在研究PSR-7接口并思考如何实现它们的方法。

我也一直在阅读这篇博文。显然,实现PSR-7接口的对象必须是不可变的。

因此,如果我从那时起实现该withProtocolVersion方法,MessageInterface它将如下所示:

public function withProtocolVersion($version)
{
    if ( $this->protocol === $version )
    {
        return $this;
    }

    $new = clone $this;
    $new->protocol = $version;
    return $new;
}

我的问题真的是,为什么不可变?为什么不简单地做一个return $this;

并不是我担心它分配的内存量,我只是真的看不出保持它不可变有什么好处。

就像博客文章说的那样,当你这样做时:

$request = $request
    ->withMethod('POST')
    ->withUrl(new Url('http://example.org/')
    ->withHeader('Content-Type', 'text/plain');

然后创建了四个副本,但最终结果$request与我简单地使用时相同return $this,对吗?

为什么决定让它保持不变。那么我为什么要做一个clone $this?它有什么好处?

我并没有真正开始这个想法。

4

1 回答 1

9

我建议您阅读此文档,其中详细解释了所有设计选择。

特别是您应该阅读Why value objects?New instances vs returning $this部分。

要点如下:

本质上,将 HTTP 消息建模为值对象可确保消息状态的完整性,并防止需要双向依赖,这通常会不同步或导致调试或性能问题。

这些操作也可以用值对象来完成,有很多好处:

  • 可以存储原始请求状态以供任何消费者检索。
  • 可以使用默认标头和/或消息正文创建默认响应状态。

如果您想更深入地挖掘,我建议您查看 fig 邮件列表的历史(您可以在此处找到),其中有很多关于对象不变性的讨论

于 2015-07-11T20:08:04.190 回答