?

Log in

No account? Create an account

Заповедник репрессивной психиатрии

Creeping fields
metaclass
Не знаю, что делать с одной гнилой проблемой. Вернее, знаю что, но это мне ничем не поможет.
Дано: продукт со сложной бизнес-логикой. Множество разнообразных клиентов, которые используют эту бизнес-логику, и у каждого по сути работы имеются различные требования к ней. Очевидно, поддерживать 10 версий продукта никакого желания нет, поэтому различные требования объединяются до кучи и все сводится к единообразному коду. Подгружаются различные классы-обработчики там исходя из настроек и считают что надо.

Но проблема в том, что при каждому из этих вариантов нужен свой набор входных данных, а каждому варианту входных данных - свой GUI. В итоге работа по добавлению нового функционала на 50% состоит из "добавить поле в таблицу, добавить поле в объект, добавить поле на экран". Причем каждый из пользователей использует только часть всего этого добра, а остальное оставляется незаполненным. И это сильно действует на нервы.

В итоге эта пакость ползучим образом разрастается до типичного "окна ввода данных в производственную систему". Видели когда-нибудь окна у бухгалтеров в ЖЭСе, в 1С, или там в банках? 20 закладок, пару сотен полей. Вот это оно самое и есть. Понадобилась новая аналитика в отчетах - добавили поле всюду, дописали отчеты. И так годами, пока там этих аналитик не наберется столько, что никто уже не помнит зачем оно. И хорошо еще если аналитика эта тупым group by собирается, а то еще иногда бывает что ее какими-то адскими расчетами учитывать надо.

Комбинации используемых полей устроены таким образом, что оформить это в виде иерархии наследуемых классов не получается. Кроме того, при наследовании класса модели данных приходится наследовать еще несколько штук классов(редактор, orm, и прочая хрень), и в каждом из них задалбываться с проверками "а того ли мы класса объект получили" и преобразовывать типы.

Если бы мы писали на нормальных языках - то каждый вариант использования можно было бы вытащить в некий подзагружаемый модуль с описаниями полей, их маппинга в БД и редакторов, который при старте программы бы комбинировался с такими же и тут же бы компилировался/интерпретировался в выполняемый код. И ключевой момент - чтобы это дело сразу строго типизированным было, без всяких преобразований долбаных и проверок.

Но: с реляционными БД такого не сделаешь. Т.е. просто так удалить-добавить поля при старте программы не выйдет. Обновления БД становятся адом. Если использовать вертикальное хранение атрибутов объектов - это можно сделать, но запросы тогда превращаются в нечеловеческую тыкву и тормозит это все адски. Если же нужно добавить не поле, а например подчиненную таблицу со списком детализации - воще гамон.

В коде тоже радости мало - сиди как пень и реализовывай поверх обычного языка с объектами, объектную систему еще раз. Я видел такие реализации, ну оно конечно мегаинтересно с точки зрения программиста ("да что нам свой язык сделать стоит") но каждый раз результат получался весьма печальным - свой птичий язык, тормозит, радости никакой. И GUI все равно руками рисовать, вместо генератора автоматического.

PS: И кстати, использование реляционных БД тут ключевой аспект - как только начинаются поползновения в сторону "изолируемся от БД", "а не использовать ли нам объектную БД" - это еще больше все усложняет, ничего не решая реально. Дело в том, что из всех вариантов составления выходных отчетов и вообще работы с данными, SQL наиболее лаконичен и понятен(не считая хаскеля, конечно). И общеизвестен. А остальное все мрак нечеловеческий.