Should I use new self or new static?
Asked Answered
R

1

8

I work on a proprietary project that uses quite a lot of factories of one form or another. Most of them don't instantiate the class by name, fortunately, but whether new self() or new static() is used to instantiate varies depending on the developer.

I'm aware of the difference, but I'm curious if there's some consensus on which one is the "correct" way to go when late static binding isn't technically required. For instance, new static() is often found in service classes that will almost certainly never be subclassed. It's obviously important in abstract classes, but my preference would be to use new self() where I don't expect a subclass.

Questions that address the technical difference:

What I'm curious about:

  • Is there a performance hit to using late static binding?
  • Are there code maintenance implications to adopting one practice? Eg. If I subclass a class using new self(), I have to override/change all such cases, but maybe that's not a bad thing if my constructor changes.
  • Is there a documented best practice on this? We use PSR-2, at least aspirationally, but I don't think it covers this.
Royston answered 20/10, 2017 at 13:10 Comment(1)
For question 1 (is there a performance hit), please benchmark some actual classes of yours by instatiating them 1M times or similiar.Oxidimetry
E
10

First, lets discuss the difference for a moment:

Returning new static will result in an instance of the derived class, meaning if Foo declares static method Create() (a factory method) that returns a new static, then calling Foo::Create() or self::Create() from Foo will return an instance of Foo. However, if class Bar extends Foo, and you call Bar::Create(), it'll return an instance of Bar.

Thus, if you want Bar::Create() to return an instance of Foo, you should use new self, not new static.

Considering developer expectations that static factory methods such as Create() return instances of the derived classes, I'd argue that returning the late-bound type is likely the right answer in most circumstances. However if a class is marked final (sealed, closed to extension), then it doesn't matter. Assuming a class isn't final, (which presumes others are allowed to extend it), static is likely the right choice.

As far as performance goes; given PHP is interpreted, I can't imagine it has significant performance implications. This is really a discussion about what is more correct/semantic, and to reiterate, I think returning a new static is the correct answer most of the time, with returning a new self being the exception in specific circumstances.

Note that this question is actually pretty similar to here: Is it possible to overuse late static binding in PHP?. You may find that answer useful, too.

Epicurean answered 20/10, 2017 at 13:57 Comment(1)
You can always declare a class as final.Royston

© 2022 - 2024 — McMap. All rights reserved.