И так, ситуация: Мы разрабатываем клиент-серверные приложения, постоянно работаем с большим количеством сущностей и планируем использовать автогенерацию кода на основе описаний объектов.
Стандартные инструменты 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 использовать точно не будем\не можем\не хотим.