Коли методи батьківського та дочірнього класів конфліктують
TL;DR: Уникайте використання приватних методів у батьківських класах з іменами, які можуть бути використані дочірніми класами.
Проблеми
- Порушення принципу найменшої несподіванки
- Неочікувана поведінка та дефекти
- Приховані залежності
- Обмежена можливість розширення
- Амбівалентність коду
- Порушення принципу відкритості/закритості
- Оманливий дизайн
Рішення
- Уникайте ієрархій
- Перейменовуйте приватні методи
- Дотримуйтеся чіткого найменування
- Уникайте повторення імен
- Уникайте захищених методів
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] Середній
Чому важлива бієкція
Чіткий та передбачуваний код має відображати реальні відносини, які він моделює.
Коли ви використовуєте приватні методи з перекритими іменами, ви створюєте розрив бієкції між моделлю та реалізацією.
Цей розрив збиває з пантелику розробників, збільшує кількість дефектів і порушує принципи чистого коду.
Генерація ІІ
Генератори ІІ часто створюють цей запах, коли генерують шаблонні батьківсько-дочірні відносини.
Вони можуть не перевіряти рівні доступу або враховувати наслідки успадкування.
Виявлення ІІ
Інструменти ІІ можуть виправити цей запах з чіткими інструкціями.
Ви можете попросити ІІ перевірити на наявність перекриваючих імен методів і рефакторити ієрархії.
Спробуйте це!
Не забувайте: помічники ІІ часто роблять багато помилок
Без належних інструкцій
Коли методи батьківського і дочірнього класів збігаються
TL;DR: Уникайте використання приватних методів у батьківських класах з іменами, які можуть бути використані в дочірніх класах.
Проблеми
- Порушення принципу найменших сюрпризів
- Неочікувана поведінка та дефекти
- Приховані залежності
- Обмежена розширюваність
- Неясність коду
- Порушення принципу відкритості/закритості
- Оманливий дизайн
Рішення
- Уникайте ієрархій
- Перейменуйте приватні методи
- Підтримуйте чітке найменування
- Уникайте перекриття імен
- Уникайте захищених методів
6. - ChatGPT
- 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