5

我从事一个专有项目,该项目使用了相当多的一种或另一种形式的工厂。幸运的是,它们中的大多数不按名称实例化类,但是否new self()用于new static()实例化取决于开发人员。

我知道其中的区别,但我很好奇当后期静态绑定在技术上不是必需的时,是否有一些共识是“正确”的方式。例如,new static()经常出现在几乎可以肯定永远不会被子类化的服务类中。这在抽象类中显然很重要,但我更喜欢new self()在我不期望子类的地方使用。

解决技术差异的问题:

我好奇的是:

  • 使用后期静态绑定是否会影响性能?
  • 采用一种做法是否会对代码维护产生影响?例如。如果我使用 子类化一个类new self(),我必须重写/更改所有此类情况,但如果我的构造函数发生更改,这可能不是一件坏事。
  • 是否有记录在案的最佳实践?我们使用 PSR-2,至少是有抱负的,但我不认为它涵盖了这一点。
4

1 回答 1

7

首先,让我们讨论一下区别:

返回 new static 将导致派生类的实例,这意味着如果 Foo 声明返回 a 的静态方法 Create() (工厂方法)new static,那么从 Foo 调用Foo::Create()orself::Create()将返回 Foo 的实例。但是,如果class Bar extends Foo,并且您调用Bar::Create(),它将返回 Bar 的一个实例。

因此,如果你想Bar::Create()返回一个 Foo 的实例,你应该使用 new self,而不是 new static。

考虑到开发人员期望 Create() 等静态工厂方法返回派生类的实例,我认为在大多数情况下返回后期绑定类型可能是正确的答案。但是,如果一个类被标记final(密封,对扩展关闭),那就没关系了。假设一个类不是最终的(假设允许其他人扩展它),静态可能是正确的选择。

就性能而言;鉴于 PHP 已被解释,我无法想象它会对性能产生重大影响。这实际上是关于什么更正确/语义的讨论,重申一下,我认为返回一个新的静态是大多数时候的正确答案,在特定情况下返回一个新的自我是例外。

请注意,这个问题实际上与此处非常相似:Is it possible to overuse late static binding in PHP? . 您可能会发现该答案也很有用。

于 2017-10-20T13:57:26.317 回答