Когда родительские и дочерние методы сталкиваются!
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
Вы можете обнаружить этот запах, посмотрев на частные методы в родительских классах и проверив, определяют ли дочерние классы методы с тем же именем. Вы также должны проверить родительские методы, вызывающие частные методы.
Понятный и предсказуемый код должен отражать реальную иерархию, которую он моделирует.
При использовании закрытых методов с перекрывающимися именами создается разрыв биекции между моделью и реализацией.
Этот пробел сбивает с толку разработчиков, увеличивает количество дефектов и нарушает принципы чистого кода.
Генераторы искусственного интеллекта часто создают этот запах, когда генерируют шаблонные родительско-детские отношения.
Они могут не проверять уровни доступа или не учитывать последствия наследования.
Инструменты ИИ могут устранить этот запах с помощью четких инструкций.
Вы можете попросить ИИ проверить наличие перекрывающихся имен методов и рефакторинг иерархий.
Попробуйте!
Помните: помощники на основе искусственного интеллекта совершают много ошибок
Без надлежащих инструкций | С конкретными инструкциями |
---|---|
При проектировании родительских и дочерних классов следует использовать методы, которые четко определяют наследование и доступность.
Избегайте частных методов, которые перекрываются с дочерними методами. Это сохраняет ваш код читаемым, расширяемым и соответствующим принципам чистого кода.
Такие языки, как 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.