Wanneer ouder- en kindmethoden botsen!
TL;DR: Vermijd het gebruik van privémethoden in bovenliggende klassen met namen die ook door onderliggende klassen gebruikt kunnen worden.
Wanneer u dezelfde methodenaam gebruikt in bovenliggende en onderliggende klassen, ontstaat er verwarring.
Een privémethode in de bovenliggende klasse kan niet worden overschreven, zelfs niet als er een openbare methode met dezelfde naam in de onderliggende klasse bestaat.
Dit is een probleem dat de meeste statische talen in hun ontwerp hebben. Deze ontkoppeling leidt tot bugs en maakt uw code moeilijk te onderhouden.
<? class ParentClass { private function greet() { // This method is private return "Hello from ParentClass"; } public function callGreet() { return $this->greet(); } } class ChildClass extends ParentClass { public function greet() { // Overriding a concrete method is a code smell // Compilers SHOULD warn you return "Hello from ChildClass"; } } $child = new ChildClass(); echo $child->callGreet(); // When callGreet() is invoked on the $child object, // it executes the following: // It calls $this->greet(), // which refers to the greet() method of ParentClass // because the original method is private // and cannot be overridden or accessed from ChildClass. // The unexpected output is 'Hello from ParentClass'
<? class ParentClass { protected function greet() { // notice the 'protected qualifier' return "Hello from ParentClass"; } public function callGreet() { return $this->greet(); } } class ChildClass extends ParentClass { public function greet() { return "Hello from ChildClass"; } } $child = new ChildClass(); echo $child->callGreet(); // The output is "Hello from ChildClass" // This is the standard (and wrong) solution // Also fixed by most AIs
<? abstract class ParentClass { // Declare greet() as an abstract method // Following the template-method design pattern abstract protected function greet(); public function callGreet() { return $this->greet(); } } class ChildClass extends ParentClass { protected function greet() { return "Hello from ChildClass"; } } class OtherChild extends ParentClass { protected function greet() { return "Hello from OtherChild"; } } $child = new ChildClass(); echo $child->callGreet(); // Output: Hello from ChildClass $otherChild = new OtherChild(); echo $otherChild->callGreet(); // Output: Hello from OtherChild
U kunt deze geur detecteren door te zoeken naar private methoden in bovenliggende klassen en te controleren of onderliggende klassen methoden met dezelfde naam definiëren. U moet ook bovenliggende methoden testen die private methoden aanroepen.
Duidelijke en voorspelbare code moet de hiërarchie uit de echte wereld weerspiegelen die het modelleert.
Wanneer u privémethoden met overlappende namen gebruikt, ontstaat er een bijectiekloof tussen het model en de implementatie.
Deze kloof verwart ontwikkelaars, vergroot het aantal defecten en schendt de principes van schone code.
AI-generatoren creëren deze geur vaak wanneer ze standaard ouder-kindrelaties genereren.
Het kan zijn dat ze de toegangsniveaus niet controleren en geen rekening houden met de gevolgen van overerving.
AI-hulpmiddelen kunnen deze geur verhelpen met duidelijke instructies.
U kunt de AI vragen om te controleren op overlappende methodenamen en refactoringhiërarchieën.
Probeer ze eens!
Onthoud: AI-assistenten maken veel fouten
Zonder de juiste instructies | Met specifieke instructies |
---|---|
Bij het ontwerpen van bovenliggende en onderliggende klassen moet u methoden gebruiken die overerving en toegankelijkheid duidelijk definiëren.
Vermijd private methoden die overlappen met child-methoden. Dit houdt uw code leesbaar, uitbreidbaar en afgestemd op clean code-principes.
Met talen als Python kunt u bovenliggende methoden overschrijven, ongeacht hun naam, terwijl Java strikte toegangslevels afdwingt.
C# gedraagt zich vergelijkbaar met Java . Deze verschillen betekenen dat u de specifieke regels van de taal waarmee u werkt moet begrijpen om onverwacht gedrag te voorkomen.
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxviii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iii-t7h3zkv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-viii-8mn3352
Disclaimer: Code Smells zijn mijn mening .
Overerving is goed, maar je moet nooit vergeten dat het een nauwe koppeling met zich meebrengt.
Robert C. Martin
Dit artikel is onderdeel van de CodeSmell-serie op HackerNoon.