Private vs Protected Methods: The Debate That Never Ends
Image by chrisjohnbeckett via Flickr
As a new generation of PHP web application frameworks start establishing beach heads in preparation for an all out war for mindshare, I've been contemplating some of the key changes we're seeing emerge that may gain traction over time. Today, I just thought to share my thoughts about private methods vs protected methods. Something that has impacted on Doctrine 2 and Symfony 2. And every other piece of PHP code since PHP 4 came along.
Doctrine and Symfony have adopted a practice whereby all methods are flagged as private unless there are compelling reasons to the contrary (i.e. they are necessarily part of a public API, or form part of an abstract implementation). There is an allowance for appealing that a method be switched from private to protected on a case by case basis.
I'm not a big fan of private methods. I'm in a state of persistent internal conflict over them, in fact. At this point in time, I am in favour of protected methods over private methods.
On one hand, there's the traditional idea that private methods must never be used outside the current class to prevent interaction with and dependencies on highly unstable units of behaviour. This is a common need arising out of refactoring where non-public methods may vanish, move classes, get renamed or find themselves saddled with different behaviour. These non-public methods are inherently unstable. There is no getting away from that. While this is perfectly normal during development, it can become an irritating concept downstream if you are depending on such implementation details in your own work.
On the other hand, non-public methods contain the meat of any class - the implementation specifics. Using Inheritance, you can extend classes containing this implementation code at very little cost if they are carried by protected methods. This usually tends to make life easier, promotes source code reuse, allows for bug and security fixes ahead of schedule (assuming there it's not one of those lost bugs that will never be fixed), dependence on existing implementation facets, etc. This all does, however, carry the risk of creating a lot of brittle code that may break at the next update due to the effects of refactoring.
These two strands of thought have been in combat for a long time in many programming languages. It's no different in PHP. Many developers are likely under the delusion that protected methods constitute a protected API, i.e. that there is a rule that protected methods must retain backwards compatibility across updates. There is no such rule. There is, however, a form of peer pressure to conform to these delusions. Ask any set of developers about backwards compatibility and there's probably a fair chance that the majority will insist that it applies to protected methods. Unfortunately, this is in direct violation of the principles behind refactoring. In other words, it's a delusional belief with no basis in software engineering. Since delusional is a strong term, I'll refer to it as the misguided status quo. There - that's surely less offensive.
In my view, this is where PHP developers seem to like throwing themselves off a cliff. Rather than perform refactoring, they would rather preserve backwards compatibility on methods that are not even unit tested. All for a group of people down the line who are unwilling to accept that they took a risk in depending on them. If that sounds a wee bit bitter, it is. I've seen people do some crazy weird shit to avoid refactoring or other key changes that would make my life s
Truncated by Planet PHP, read more at the original (another 4456 bytes)