I just read Matthew Weier O’Phinney’s On Visibility in OOP. Aside from being an excellent and easy to follow explanation of
final in PHP, MWOP’s experiences dealing with private and final in framework and library classes somewhat echo my own.
In the example he presented, he was unable to extend and improve
Doctrine\Common\Annotations\DocParser due to the fact that it has private members and is marked as
final. This proved a significant roadblock to interoperability between Zend Framework 2 and Doctrine 2.
In my case, I also encountered a roadblock in Doctrine 2, but for me it was a block to testability.
Doctrine\ORM\EntityManager is marked as
final, and while I understand the reasoning behind the statement “this should not be extended”, I would propose that in the case of creating tests, this reasoning no longer applies. To allow the flexibility necessary to create effective tests, it is frequently necessary to extend a class in order to create a mock or proxy. If the class in question is
final or makes most of its inner workings
private, we must resort to overly complex and less realistic methods to create tests for code that touches it. This in turn decreases the chances that our tests are actually covering the cases we intend them to cover and increases the chances of false positives and false negatives from the test suite. In short, we’re forced to choose between “hacking” someone else’s code to change visibility or creating very brittle tests.