Code Smell 286 — Перекриття методів

Коли методи батьківського та дочірнього класів конфліктують

pic

TL;DR: Уникайте використання приватних методів у батьківських класах з іменами, які можуть бути використані дочірніми класами.

Проблеми

  • Порушення принципу найменшої несподіванки
  • Неочікувана поведінка та дефекти
  • Приховані залежності
  • Обмежена можливість розширення
  • Амбівалентність коду
  • Порушення принципу відкритості/закритості
  • Оманливий дизайн

Рішення

  1. Уникайте ієрархій
  2. Перейменовуйте приватні методи
  3. Дотримуйтеся чіткого найменування
  4. Уникайте повторення імен
  5. Уникайте захищених методів
    6.
    Уникайте підкласів для необхідних відносин, а не для повторного використання коду

Контекст

Коли ви використовуєте однакові імена методів у батьківському та дочірньому класах, це викликає непорозуміння.

Приватний метод у батьківському класі не може бути перекритий, навіть якщо в дочірньому класі існує публічний метод з таким самим ім’ям.

Це проблема, з якою стикаються більшість статичних мов у своїй розробці.

Цей розрив призводить до помилок і ускладнює підтримку коду.

Приклад коду

Неправильний

greet();  
 }  
}class ChildClass extends ParentClass {  
 public function greet() {  
 // Перекриття конкретного методу є запахом коду  
 // Компілятори МАЮТЬ попереджати про це  
 return "Hello from ChildClass";  
 }  
}$child = new ChildClass();  
echo $child->callGreet();// Коли викликається callGreet() для об'єкта $child,  
// він виконує наступне:  
// Викликає $this->greet(),   
// що посилається на метод greet() класу ParentClass   
// тому що оригінальний метод є приватним   
// і не може бути перекритий або доступний з ChildClass.// Неочікуваний результат: 'Hello from ParentClass'

Правильний

greet();  
 }  
}class ChildClass extends ParentClass {  
 public function greet() {  
 return "Hello from ChildClass";  
 }  
}$child = new ChildClass();  
echo $child->callGreet();// Результат: "Hello from ChildClass"  
// Це стандартне (але неправильне) рішення  
// Також виправлено більшістю ІІ  
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(); // Результат: Hello from ChildClass$otherChild = new OtherChild();  
echo $otherChild->callGreet(); // Результат: Hello from OtherChild

Виявлення

[X] Напівавтоматичне

Ви можете виявити цей запах, шукаючи приватні методи у батьківських класах і перевіряючи, чи визначають дочірні класи методи з таким самим ім’ям.

Ви також повинні тестувати методи батьків, які викликають приватні методи.

Теги

  • Ієрархія

Рівень

[X] Середній

Чому важлива бієкція

Чіткий та передбачуваний код має відображати реальні відносини, які він моделює.

Коли ви використовуєте приватні методи з перекритими іменами, ви створюєте розрив бієкції між моделлю та реалізацією.

Цей розрив збиває з пантелику розробників, збільшує кількість дефектів і порушує принципи чистого коду.

Генерація ІІ

Генератори ІІ часто створюють цей запах, коли генерують шаблонні батьківсько-дочірні відносини.

Вони можуть не перевіряти рівні доступу або враховувати наслідки успадкування.

Виявлення ІІ

Інструменти ІІ можуть виправити цей запах з чіткими інструкціями.

Ви можете попросити ІІ перевірити на наявність перекриваючих імен методів і рефакторити ієрархії.

Спробуйте це!

Не забувайте: помічники ІІ часто роблять багато помилок

Без належних інструкцій

Коли методи батьківського і дочірнього класів збігаються

pic

TL;DR: Уникайте використання приватних методів у батьківських класах з іменами, які можуть бути використані в дочірніх класах.

Проблеми

  • Порушення принципу найменших сюрпризів
  • Неочікувана поведінка та дефекти
  • Приховані залежності
  • Обмежена розширюваність
  • Неясність коду
  • Порушення принципу відкритості/закритості
  • Оманливий дизайн

Рішення

  1. Уникайте ієрархій
  2. Перейменуйте приватні методи
  3. Підтримуйте чітке найменування
  4. Уникайте перекриття імен
  5. Уникайте захищених методів
    6.
  6. ChatGPT
  7. Gemini

З конкретними інструкціями

Висновок

При проектуванні батьківських і дочірніх класів слід використовувати методи, які чітко визначають успадкування та доступність.

Уникайте приватних методів, що перекривають методи дочірніх класів.

Це дозволить зробити ваш код зрозумілим, розширюваним і відповідним принципам чистого коду.

Мови програмування, такі як Python, дозволяють перекривати методи батьків, незалежно від їхніх назв, тоді як Java суворо дотримується рівнів доступу.

C# поводиться подібно до Java.

Ці відмінності означають, що ви повинні розуміти конкретні правила мови, з якою працюєте, щоб уникнути непередбачуваної поведінки.

Відносини

[

Code Smell 137 — Занадто глибоке дерево успадкування

Ще одна ознака поганого повторного використання коду

levelup.gitconnected.com

](/code-smell-137-inheritance-tree-too-deep-541590a56bd5?source=post_page-----5fc1d539b9ff--------------------------------)

[

Code Smell 58 — Проблема йо-йо

Шукаєте реалізацію конкретного методу? Повертайтесь назад, вгору і вниз.

blog.devgenius.io

](https://blog.devgenius.io/code-smell-58-yo-yo-problem-1e092d3c69ff?source=post_page-----5fc1d539b9ff--------------------------------)

[

Code Smell 11 — Підкласування для повторного використання коду

Повторне використання коду — це добре.

Але підкласування генерує статичне зв'язування.

blog.devgenius.io

](https://blog.devgenius.io/code-smell-11-subclassification-for-code-reuse-2e2f5b564204?source=post_page-----5fc1d539b9ff--------------------------------)

[

Code Smell 125 — Відносини "IS-A"

Ми вчилися в школі, що успадкування представляє відносини "is-a". Це не так.

mcsee.medium.com

](https://mcsee.medium.com/code-smell-125-is-a-relationship-3de263ab437d?source=post_page-----5fc1d539b9ff--------------------------------)

[

Code Smell 37 — Захищені атрибути

Захищені атрибути чудово підходять для інкапсуляції та контролю доступу до наших властивостей. Вони можуть попереджати нас про...

blog.devgenius.io

](https://blog.devgenius.io/code-smell-37-protected-attributes-4607260edb2d?source=post_page-----5fc1d539b9ff--------------------------------)

Відмова від відповідальності

Code Smells — це моя думка.

Подяки

Фото зроблене Matt Artz на Unsplash

Успадкування — це добре, але ви не повинні забувати, що воно вводить тісне зв'язування.

Роберт С. Мартін

[

Великі цитати з програмної інженерії

Іноді коротка думка може привести до неймовірних ідей.

blog.devgenius.io

](https://blog.devgenius.io/software-engineering-great-quotes-3af63cea6782?source=post_page-----5fc1d539b9ff--------------------------------)

Ця стаття є частиною серії CodeSmell.

[

Як знайти смердючі частини вашого коду

Код пахне погано. Давайте подивимося, як змінити ці аромати.

blog.devgenius.io

](https://blog.devgenius.io/how-to-find-the-stinky-parts-of-your-code-fa8df47fc39c?source=post_page-----5fc1d539b9ff--------------------------------)

Перекладено з: Code Smell 286 — Overlapping Methods

Leave a Reply

Your email address will not be published. Required fields are marked *