Коли батьківський і дитячий методи стикаються!
TL;DR: уникайте використання приватних методів у батьківських класах з іменами, які можуть використовувати дочірні класи.
Коли ви використовуєте однакову назву методу в батьківських і дочірніх класах, ви створюєте плутанину.
Приватний метод у батьківському класі не можна перевизначити, навіть якщо публічний метод із такою ж назвою існує в дочірньому класі.
Це проблема більшості статичних мов у своєму дизайні. Це роз’єднання призводить до помилок і ускладнює підтримку коду.
<? 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
Ви можете виявити цей запах, шукаючи приватні методи в батьківських класах і перевіряючи, чи дочірні класи визначають методи з однаковою назвою. Ви також повинні протестувати батьківські методи, викликаючи приватні методи.
Чіткий і передбачуваний код повинен відображати ієрархію реального світу, яку він моделює.
Коли ви використовуєте приватні методи з іменами, що перекриваються, ви створюєте розрив Bijection між моделлю та реалізацією.
Ця прогалина заплутує розробників, збільшує кількість дефектів і порушує принципи чистого коду.
Генератори штучного інтелекту часто створюють цей запах, коли створюють шаблонні стосунки «батьки-діти».
Вони можуть не перевіряти рівні доступу або враховувати наслідки успадкування.
Інструменти ШІ можуть виправити цей запах за допомогою чітких інструкцій.
Ви можете попросити штучний інтелект перевірити назви методів та ієрархії рефакторів, які збігаються.
Спробуйте їх!
Пам’ятайте: помічники ШІ роблять багато помилок
Без відповідних інструкцій | З конкретними інструкціями |
---|---|
При проектуванні батьківських і дочірніх класів ви повинні використовувати методи, які чітко визначають успадкування та доступність.
Уникайте приватних методів, які накладаються на дочірні методи. Це зберігає ваш код читабельним, розширюваним і узгодженим із принципами чистого коду.
Такі мови, як Python, дозволяють перевизначати батьківські методи незалежно від їхніх імен, тоді як Java суворо забезпечує рівні доступу.
C# поводиться подібно до Java . Ці відмінності означають, що вам потрібно розуміти конкретні правила мови, з якою ви працюєте, щоб уникнути несподіваної поведінки.
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
Відмова від відповідальності: Code Smells — це моя думка .
Кредити: фото Метта Арца на Unsplash
Спадкування – це добре, але ви ніколи не повинні забувати, що воно вводить тісний зв’язок.
Роберт С. Мартін
Ця стаття є частиною серії CodeSmell на HackerNoon.