我正在研究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
呢?它有什么好处?
我并没有真正想到这个想法。
答案 0 :(得分:9)
我建议你阅读this document,其中详细解释了所有设计选择。
特别要阅读Why value objects?
和New instances vs returning $this
部分。
关键点如下:
本质上,将HTTP消息建模为值对象可确保消息状态的完整性,并防止需要双向依赖,这通常会导致不同步或导致调试或性能问题。
和
这些操作也可以使用值对象来完成,具有许多好处:
- 可以存储原始请求状态以供任何消费者检索。
- 可以使用默认标头和/或邮件正文创建默认响应状态。
如果你想深入挖掘,我建议你查看无花果邮件列表的历史(你可以找到here),其中有很多关于对象不变性的讨论< / p>