Re: Re: Getting rid of "underscore for private method names" codingstandard
| From: | Kornel Lesiński | Date: | Wed, 03 Feb 2010 12:56:09 +0000 |
| Subject: | Re: Re: Getting rid of "underscore for private method names" codingstandard | ||
| References: | 1 2 3 4 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-53260@lists.php.net to get a copy of this message | ||
On 03-02-2010 at 11:57:53 Daniel O'Connor <daniel.oconnor@gmail.com> wrote:
<?php /** A, the handy package from PEAR, who's source code you cannot easily modify */ class A { private function performSecretCalculation($a, $b) {BTW: in this particular example a better override would be -1*parent::add($a,$b), which doesn't rely on anything but public interface (I understand that your point is that it's not always possible).return $a+$b;} public function add($a, $b) {return $this->performSecretCalculation($a, $b);} } /** B, a class which leverages A, for your specific conditions */ class B extends A { /*** @todo Work out what jerk made me reimplement this method by cut andpasting.* when all I wanted to do was make a different implementation ofadd()*/private function performSecretCalculation($a, $b) {return $a+$b;} public function add($a, $b) {return -1 * $this->performSecretCalculation($a, $b);}
} $a = new A(); print $a->add(1, 2); $b = new B(); print $b->add(1, 2);class A /* version 1.1 */ { // I've realised that performSecretCalculation was a bad idea and got rid of it. public function add($a, $b) { return $a + $b; } } Thanks to encapsulation, your class still works (you have copy of method I've removed). Mine could be freely refactored. However, if performSecretCalculation was only "protected", your code would be allowed to rely on secret implementation detail that is now gone, and your code would break. I'll reiterate my statement: protected methods in non-final classes are de-facto public interface of the class. Public interface is not allowed to change. If all methods are protected/public, author of the class can never remove or significantly change any methods. Refactoring becomes impossible or at least requires addition of backwards-compatibility layers (which can never be removed themselves, and are tricky to implement - see below). Base classes are pain to maintain. Let's say that performSecretCalculation has always been protected or public, and I've changed implementation to: class A { public function performSecretCalculation($a, $b) {
return $this->add($a,$b); // Moved code around. Addition makes more sense in add()!} public function add($a, $b) { return $a + $b; } } That class would pass all unit tests. Interface hasn't changed at all. Code that used composition instead of inheritance wouldn't break. But your code that calls performSecretCalculation() in add() would break badly (crash mod_php without emitting meaningful error). That's a huge can of worms to open just so that someone may avoid copy&paste of methods that he wasn't supposed to be using in a first place. -- regards, Kornel