Какой код лучше, может зависеть от опыта программистов, а также от инструментов, которые они используют. Например, вот почему то, что обычно считается плохо написанным кодом, может быть более эффективным в некоторых ситуациях, чем хорошо написанный объектно-ориентированный код, который полностью использует наследование:
(1) Некоторые программисты просто не имеют интуитивного понимания объектно-ориентированного программирования. Если ваша метафора для программного проекта представляет собой электрическую цепь, то вы ожидаете много дублирования кода. Вам понравится видеть более или менее одинаковые методы во многих классах. Они заставят вас чувствовать себя как дома. И проект, в котором вам нужно искать методы в родительских или даже в родительских классах, чтобы увидеть, что происходит, может показаться враждебным. Вы не хотите понимать, как работает родительский класс, а затем понимать, чем отличается текущий класс. Вы хотите непосредственно понять, как работает текущий класс, и вы находите факт, что информация распределена по нескольким файлам, сбивает с толку.
Кроме того, когда вы просто хотите исправить конкретную проблему в определенном классе, вам может не понравиться думать, решать ли проблему непосредственно в базовом классе или перезаписывать метод в вашем текущем интересующем классе. (Без наследования вам не пришлось бы принимать осознанное решение. По умолчанию просто игнорируются похожие проблемы в похожих классах, пока они не будут сообщены как ошибки.) Этот последний аспект не является действительным аргументом, хотя он может объяснить некоторые из оппозиции.
(2) Некоторые программисты часто используют отладчик. Хотя в целом я твердо на стороне наследования кода и предотвращения дублирования, я разделяю некоторые разочарования, описанные в (1), при отладке объектно-ориентированного кода. Когда вы следите за выполнением кода, он иногда переходит между классами (предками), даже если он остается в том же объекте. Кроме того, при установке точки останова в хорошо написанном коде она с большей вероятностью срабатывает, когда это не помогает, поэтому вам, возможно, придется потратить усилия на то, чтобы сделать ее условной (где это целесообразно), или даже на ручное продолжение много раз перед соответствующим триггером.