Мне интересно, что лучше с точки зрения хорошего ООП-дизайна, чистого кода, гибкости и предотвращения запаха кода в будущем. Ситуация с изображением, когда у вас есть много очень похожих объектов, которые вы должны представлять как классы. Эти классы не имеют никакой конкретной функциональности, только классы данных и отличаются только по имени (и контексту). Пример:
Class A
{
String name;
string description;
}
Class B
{
String name;
String count;
String description;
}
Class C
{
String name;
String count;
String description;
String imageUrl;
}
Class D
{
String name;
String count;
}
Class E
{
String name;
String count;
String imageUrl;
String age;
}
Было бы лучше держать их в отдельных классах, чтобы получить «лучшую» читаемость, но с большим количеством повторений кода, или лучше использовать наследование, чтобы быть более СУХИМЫМ?
Используя наследование, вы получите что-то подобное, но имена классов утратят контекстное значение (из-за is-a, а не has-a):
Class A
{
String name;
String description;
}
Class B : A
{
String count;
}
Class C : B
{
String imageUrl;
}
Class D : C
{
String age;
}
Я знаю, что наследование не используется и не должно использоваться для повторного использования кода, но я не вижу другого возможного способа уменьшить повторение кода в таком случае.
источник
В точку. Посмотрите на это вне контекста:
Какими свойствами обладает D? Ты можешь запомнить? Что если вы еще больше усложните иерархию:
И что тогда, если, в ужасе от ужасов, вы хотите добавить поле imageUrl к F, но не к E? Вы не можете получить это из C и E.
Я видел реальную ситуацию, когда у множества разных типов компонентов было имя, идентификатор и описание. Но это было не по природе их составляющих, это было просто совпадение. У каждого был идентификатор, потому что они были сохранены в базе данных. Имя и описание были для показа.
Продукты также имели идентификатор, имя и описание по тем же причинам. Но они не были компонентами, и не были компонентами продуктов. Вы никогда не увидите две вещи вместе.
Но какой-то разработчик прочитал о DRY и решил, что он удалит все намеки на дублирование из кода. Поэтому он назвал все продуктом и покончил с необходимостью определить эти поля. Они были определены в Product, и все, что требовалось для этих полей, могло быть получено из Product.
Я не могу сказать это достаточно сильно: это не очень хорошая идея.
DRY не об устранении необходимости в общих свойствах. Если объект не является продуктом, не называйте его продуктом. Если Продукт НЕ ТРЕБУЕТ Описания, по самой своей природе он не определяет Описание как Свойство Продукта.
В итоге получилось, что у нас были Компоненты без описаний. Таким образом, мы начали иметь нулевые описания в этих объектах. Не обнуляется. Значение NULL. Всегда. Для любого продукта типа X ... или позже Y ... и N.
Это вопиющее нарушение принципа подстановки Лискова.
DRY - это никогда не ставить себя в положение, при котором вы можете исправить ошибку в одном месте и забыть сделать это где-то в другом месте. Этого не произойдет, потому что у вас есть два объекта с одинаковым свойством. Никогда. Так что не беспокойся об этом.
Если контекст классов делает очевидным, что вы должны, что будет очень редко, тогда и только тогда вы должны рассмотреть общий родительский класс. Но, если это свойства, подумайте, почему вы не используете интерфейс.
источник
Наследование - это способ достижения полиморфного поведения. Если у ваших классов нет поведения, то наследование бесполезно. В этом случае я бы даже не рассматривал их как объекты / классы, а вместо этого структуры.
Если вы хотите иметь возможность размещать разные структуры в разных частях вашего поведения, рассмотрите интерфейсы с методами или свойствами get / set, такими как IHasName, IHasAge и т. Д. Это сделает проект намного чище и позволит лучше их составить. вид hiearchies.
источник
Разве не для этого нужны интерфейсы? Несвязанные классы с разными функциями, но с похожим свойством.
источник
Похоже, ваш вопрос сформулирован в контексте языка, который не поддерживает множественное наследование, но конкретно не указывает это. Если вы работаете с языком, который поддерживает множественное наследование, это становится тривиально легко решить только с одним уровнем наследования.
Вот пример того, как это можно решить с помощью множественного наследования.
источник