Задать вопрос
p4s8x
@p4s8x

Чем плохи длинные цепочки наследований?

И так, ситуация: Мы разрабатываем клиент-серверные приложения, постоянно работаем с большим количеством сущностей и планируем использовать автогенерацию кода на основе описаний объектов.
Стандартные инструменты apache thrift \ protobuf нам не подошли, поэтому мы планируем писать свой велосипед.
Сгенерированный код предполагает, что в него не вносят ручных модификаций, а значит никакой логики там быть не может по определению.
Наши сгенерированные классы- это фактически набор полей(property), заданных типов, с геттерами\сеттерами и методами сериализации\десериализации.

В стандартном случае у нас сгенерированные объекты имеют какую-то цепочку наследования C_GENERATED <- B_GENERATED A_GENERATED
Мы легко можем дальше объявить свой C_CUSTOM <- C_GENERATED и добавить нужную нам логику.
Но, как поступать в случае, если логику нужно объявить в промежуточном, сгенерированном классе, например в B_GENERATED(у нас может быть еще несколько классов, наследуемых от B_GENERATED вроде CA_GENERATED<- B_GENERATED и логику требуется внести в родительский к ним класс)?
Есть два пути решения:
1) генерировать цепочку наследования с промежуточными кастомными классами: C_CUSTOM <- C_GEN <-B_CUSTOM <- B_GEN <- A_CUSTOM <- A_GEN
2) генерировать симметричную цепочку наследования C_CUSTOM <- B_CUSTOM <- A_CUSTOM, и передавать в кастомные объекты ссылку на соответствующий сгенерированный объект. Примерно это может выглядеть так:
class C_CUSTOM extends B_CUSTOM {
  var _c;
  override function setData(C_GEN c) {
    parent::setData(c);
    _c=c
  }
}
class B_CUSTOM extends A_CUSTOM {
  var _b;

  function inc(int i) {
    _b.aaa+=i;
  }
 
  override function setData(B_GEN b) {
    parent::setData(b);
     _b=b;
   }
}
c_custom=new C_CUSTOM();
c_custom.setData(c_gen);
c_custom.inc(10);


В 1 случае - у нас, единственный минус - это длинные цепочки наследования (х2 от исходного)
Во 2 случае - помимо общей громоздкости - нам, например - необходимо дополнительно выполнять кастинг исходного объекта до родителя перемещаясь по цепочке

Собственно вопрос - так ли страшно длинное наследование? Какие минусы из этого реально могут возникнуть? Может есть еще какие-то пути решения?

P.s. языко-зависимые "неооп" решения типа множественного наследования или его вариаций в виде mixin\trait использовать точно не будем\не можем\не хотим.
  • Вопрос задан
  • 443 просмотра
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 1
Smithson
@Smithson
20+ лет админю
Ничем не страшны, в памяти эти описания занимают не более сотен байт на класс (не на экземпляр). Так что не парьтесь.
Я бы выбирал вариант 1, он как-то очевиднее для меня.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы