В настоящее время у меня есть два производных класса, A
и B
оба имеют общее поле, и я пытаюсь определить, должно ли оно перейти в базовый класс.
На него никогда не ссылаются из базового класса, и говорят, что если в какой-то момент в будущем будет получен другой класс, C
который не имеет _field1
, то не нарушится ли принцип «наименее привилегированный» (или что-то еще), если он было?
public abstract class Base
{
// Should _field1 be brought up to Base?
//protected int Field1 { get; set; }
}
public class A : Base
{
private int _field1;
}
public class B : Base
{
private int _field1;
}
public class C : Base
{
// Doesn't have/reference _field1
}
Base
,A
,B
,C
и_field1
являются. Это важные детали, которые нельзя упускать; Я думаю, что вы должны отредактировать вопрос, чтобы поговорить о том, что это такое.Ответы:
Все зависит от конкретной проблемы, которую вы пытаетесь решить.
Рассмотрим конкретный пример: ваш абстрактный базовый класс есть,
Vehicle
и у вас есть конкретные реализацииBicycle
иCar
. Вы рассматриваете возможность переходаnumberOfWheels
отBicycle
иCar
до автомобиля. Должны ли вы сделать это? Нет! Потому что не у всех автомобилей есть колеса. Вы уже можете сказать, что если вы попытаетесь добавитьBoat
класс, то он сломается.Теперь, если ваш абстрактный базовый класс был
WheeledVehicle
тогда, логично иметьnumberOfWheels
переменную-член там.Вы должны применять ту же логику к своей проблеме, потому что, как видите, это не простой ответ «да» или «нет».
источник
roll()
метод, и в этом случае идея подкласса выглядит предсказуемой.Логически говоря, помимо размещения поля, реплицируемого в подклассах, по сравнению с общим в базовом классе, существует третий вариант: ввести новый подкласс в иерархию, которая имеет общие свойства между ними. @ Пит намекает на это, не заходя туда полностью.
Используя пример @ Pete, мы вводим (возможно, абстрактный) подкласс для Wheeled Vehicle, который происходит от исходного базового класса, а два подкласса происходят от него. Таким образом, исходный базовый класс не загрязнен колесами, но общность колес - СУХАЯ (не повторяется среди подклассов, имеющих колеса).
Это, конечно, может быть излишним для ваших целей, но это поддерживается механизмом иерархии классов.
источник
Я собираюсь сыграть адвоката дьявола здесь.
Прямо сейчас ты ничего не должен делать .
СУХОЙ? Нет. Но лучше иметь небольшое дублирование, чем преждевременную абстракцию, от которой потом трудно отказаться. Рефакторинг для перемещения свойства в общий базовый класс прост. Идти в другую сторону нет. Ждать и смотреть.
При принятии такого решения я склонен использовать «правило 3»: как только я повторил одну и ту же вещь, например, в трех разных местах, и только потом, могу ли я рассмотреть вопрос о его продвижении по цепочке. NB вы только в 2.
источник
В общем, я бы переместил его в базовый класс. Я не думаю, что есть цель да / нет, потому что здесь есть компромисс - перенос неиспользуемых полей против уменьшения сложности.
Я обычно предпочитаю «тяжелые» базовые классы, которые содержат все, что может быть разделено. Это упрощает сериализацию в файлы, так как вам не нужны методы сериализации потомков в каждом производном классе. Но если у вас нет такой или подобной проблемы, или, возможно, вам нужно сделать все возможное, чтобы уменьшить использование памяти, тогда только в тех полях, где они вам нужны, должно быть хорошо.
Класс-посредник, который вводит общие поля, будет хорошо, если у вас очень ограниченное количество полей. Но имейте в виду, что такой подход может значительно увеличить сложность, если у вас есть десятки полей, используемых в разных комбинациях, что приводит ко многим промежуточным классам, каждый из которых представляет определенный набор полей. Это может стать проблемой обслуживания.
источник