我应该使用新的自我还是新的静态?

时间:2017-10-20 13:10:20

标签: php late-static-binding psr-2

我在一个专有项目上工作,该项目使用了很多种形式的工厂。幸运的是,他们中的大多数都没有按名称实例化类,但是new self()new static()是否用于实例化取决于开发人员。

我知道这种差异,但是我很好奇是否有一些共识,即在技术上不需要后期静态绑定时哪一个是“正确”的方法。例如,new static()经常在服务类中找到,几乎肯定永远不会被子类化。这在抽象类中显然很重要,但我倾向于使用new self(),我不期望它是一个子类。

解决技术差异的问题:

我很好奇:

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

1 个答案:

答案 0 :(得分:7)

首先,让我们讨论一下这个差异:

返回new static将导致派生类的实例,这意味着如果Foo声明返回new static的静态方法Create()(工厂方法),则调用Foo::Create()或{{1来自Foo将返回一个Foo实例。但是,如果self::Create(),并且您致电class Bar extends Foo,则会返回Bar的实例。

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

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

就性能而言;鉴于PHP被解释,我无法想象它具有重要的性能影响。这实际上是关于什么是更正确/语义的讨论,并且重申一下,我认为在大多数情况下返回一个新的静态是正确的答案,在特定情况下返回一个新的自我是异常。

请注意,此问题实际上非常类似于此处:Is it possible to overuse late static binding in PHP?。你也可以发现这个答案很有用。