
Ниже будет длинная ввводная, по результатам коей, я не сомневаюсь, можно наговорить про меня много интересных вещей, которых хватит на несколько формуляров по 7-Б и направлений на пожизненное принудительное лечение, но вы уж дочитайте.
Это энтерпрайз, детка
На входе у нас — ПО, продукт со сложной бизнес-логикой и развитой схемой данных: данных много (десятки гигабайт), в отношениях между ними наблюдается некоторый порядок. Некоторое количество клиентов
«Различные требования» означает еще и то, что им всем (клиентам) нужны отличающиеся данные. В здравом уме никто не будет использовать разные БД под разные клиенты, потому что это

B прежде всего получается, что работа по добавлению нового поля в таблицу состоит в основном из
— «добавить в БД, добавить в таблицу, добавить в объекты, добавить в UI».
— напедалить очередной каши в аналитику/app workflow.
С учетом того, что, например, sql не подлежит компиляции, нужно быть очень аккуратным, чтобы обновить относящееся к делу во всех местах, где надо. На практике «быть аккуратным» означает, что после первой компиляции и развертывания с вероятностью 99% система не заработает. Скорее всего, и после вторых тоже — будут падения, ошибки и т.п. Это возможно до какой-то степени держать под контролем при помощи автотестов; но морально душит очень сильно.
И, наконец, второй подсад состоит вот в чем: надо добавить два поля — в 2 раза больше работы. 5 полей — … ну, вы поняли.
Постепенно эта гадость расползается по всему приложению; после года-двух приложение становится подчинено только одной задаче — разобраться, какие поля и где надо загружать/сохранять/обновлять. Примерно так: govnokod.ru/1071
Как такое могло случиться со мной? Как теперь жить дальше?
Оформлять это наследованием (Active Record и не только) — не выйдет, чаще всего просто невозможно выстроить иерархию, не сойдя с ума от поиска корректных отношений. Если забить на правильность объектной модели, то мы получим костыли, выражающиеся в том, что в каждом месте необходимо проверять, с тем ли типом объекта мы работаем — и работать по-разному. Приходим к варианту, что после «добавить в объекты» на надо будет еще и разбираться с иерархией. Кроме того, мое персональное подсознание против наследования в этом месте.
Если попытаться красиво разнести модель, например, в Entity Attribute Value, то выходит полная задница с запросами:
— писать вручную их еще хуже, чем просто понять, что происходит.
— производительность вылетает в трубу: сервер СУБД увлеченно занят join-ами, а остальное безобразно простаивает.
Еще один опробованный вариант — забыть про объекты, и юзать метаданные. Это значит, что внутри целевой БД заводится еще одна БД с метаданными, в которых по сути дублируется информация об устройстве и составе таблиц и прочего хозяйства. Для них заводится специальный редактор, формируется слой мега-абстракции (на динамических хранимках и view). С каждым ответом сервера, содержащим данные, на клиент так же едут метаданные по этим данным.
Помимо избыточности по данным и схеме, тут нас поджидает ад обновления БД, а так же то, что с самими метаданными нужно тоже работать в реляционной манере, что крайне вредно для ранимой психики разработчика: чтобы понять рекурсию, нужно понять рекурсию. Попытки втиснуть туда какое-то более-менее сложное поведение UI обречены на героический провал и комбинаторный взрыв количества метаданных, которые нужно понять/помнить (Знаете, как у нас в системе было сделано оповещение об изменении полей? Крутился поток, который по таймеру опрашивал все поля и сравнивал с закешированными значениями, выставляя флаги. Как только выбрасывалось исключение — а предыдущий разработчик даже NullReference считал номальным бизнес-кейсом — поток улетал в корку, и оповещения переставали приходить. Не торопитесь кидаться калошами, я убрал это, как только узнал. Но осадок остался, да). Да и циклы «update this — update those» никуда не делся. Fail.
А есть еще и рассинхронизация метаданных и кода логики. А есть еще и DBA у заказчика, для которых обновление становится

В поисках истины мы дошли до того, что при старте сервера приложений по описанию метаданных кодогенератор выдает семейства объектов, через Aggregation Root которых и происходит работа с ними. А на клиент при коннекте передается библиотека, которая и содержит нагенерированный инструментарий. Жесть, как она есть, короче.
Про бизнес-логику валидации, процесса и прочее я вообще молчу, там что-то страшное со скриптами на «CustomSharp» (это язык такой для
Злоключение
Я думаю, что для вас уже не секрет, что на практике я пробовал и сопровождал все описанные варианты, и ни один из них мне не понравился; правда, с последним запарок было чуть меньше, но все равно нахлебались и продолжаем черпать дерьмо погаными ведрами.
А что делать? Есть ощущение, что я сижу в насквозь дырявой лодке, которая плавает по болоту, а в руках у меня — две жестяных походных кружки, которыми можно грести к берегу, а можно выгрести всю воду. И то, и другое надо делать очень быстро, причем разобраться с приоритетами.
P.S. Если бы мы писали на каких-нибудь волшебных языках, то каждый вариант использования/сценарий/процесс можно было бы вытащить в отдельный модуль, который бы мог следить за данными, подгружаться по требованию, содержать редакторы и аттрибуты для маппинга, а при загрузке комбинироваться с остальными такими модулями — как в коде, так и через данные, общаться с БД и прозрачно делать обновление структуры. В этом волшебном языке можно безболезненно менять конфигурацию системы и продавать ее новому заказчику — ядро то же, наполнение данными/логикой другое.
Кто-нибудь знает о таком волшебном языке или системе? SAP/MDM не предлагать, это
Как, как вы воюете эту чертову дрянь руками?