Psr7 Http消息,为什么一成不变?

Viv*_*ndi 12 php psr-7

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

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

因此,如果我从那时实现该withProtocolVersion方法,MessageInterface它将看起来像这样:

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

    $new = clone $this;
    $new->protocol = $version;
    return $new;
}
Run Code Online (Sandbox Code Playgroud)

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

并不是我担心它分配的内存量,我真的没有看到保持它不可变的任何好处.

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

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

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

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

我并没有真正想到这个想法.

mar*_*osh 9

我建议你阅读这份文件,其中详细解释了所有的设计选择.

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

关键点如下:

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

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

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

如果你想深入挖掘,我建议你查看无花果邮件列表的历史(你可以在这里找到),那里有很多关于对象不变性的讨论

  • 在提供的链接中看不到原因。这个直接问题不是直接回答而是有一些联系和相同模糊的观点。关于其他开发人员可能存在的误解的意见。这向我证明,这个认真的设计决策没有充分的根据,可能仅基于php的使用方式和当前/过去的行为。 (3认同)