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

时间:2015-07-11 19:07:39

标签: php psr-7

我正在研究PSR-7接口,并考虑如何实现它们。

我也一直在阅读this blog post。显然,实现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呢?它有什么好处?

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

1 个答案:

答案 0 :(得分:9)

我建议你阅读this document,其中详细解释了所有设计选择。

特别要阅读Why value objects?New instances vs returning $this部分。

关键点如下:

  

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

  

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

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

如果你想深入挖掘,我建议你查看无花果邮件列表的历史(你可以找到here),其中有很多关于对象不变性的讨论< / p>