Обновить

Anti-corruption Layer на C#: три шва на проекте миграции с Rails

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели10K
Всего голосов 3: ↑3 и ↓0+5
Комментарии3

Комментарии 3

На практике ACL почти никогда не выглядит, как аккуратная коробка из учебника. Это не один слой, а несколько точек, где ты буквально отрезаешь легаси-хаос от домена2 где-то маппер, где-то парсер JSON, где-то правило в агрегате. И смысл не в красоте, а в том, чтобы этот мусор не расползался по коду, собрал в одном месте, перевёл в нормальные типы и дальше работаешь уже с понятной моделью, а не с наследием 10 лет боли.

>Это и есть legacy-форма, протекающая через границу. На уровне БД она оправдана

На уровне БД стоит check-constraint'ы навешать для контроля состояния. Но
1) о них почему-то реально мало знают
2) DDD-исты часто выступают против _любых_ проверок на уровне БД.

Я же считаю такие структурные проверки в БД оправданными. Стоят они дёшево, а от разных неожиданностей хорошо спасают.

Полностью согласен, я тоже в этом лагере. На примере шва №3 добавлю почему в этом кейсе констрейнт особенно к месту.

База в проекте общая: старый Rails и новый .NET пишут в одни и те же таблицы. Пока эндпоинт не переключён на .NET полностью, старый путь на Rails ещё жив и про агрегат Group.Schedule ничего не знает и может вставить пересекающуюся группу мимо него. А помимо Rails в ту же таблицу регулярно лезут рубишные rake-таски, импорты и ручные правки на проде. Доменное правило стережёт один путь записи - через .NET, а констрейнт - единственная проверка, которую соблюдают все писатели сразу. На общей БД во время Strangler Fig писатель почти никогда не один, и это мощный аргумент зачем тут такое "дублирование логики".

Про сопротивление DDD-истов: по-моему, тут важнее другой вопрос - может ли БД вообще выразить инвариант. Часть правил ей недоступна: нужен внешний контекст, чужой агрегат, вызов сервиса - такие живут только в домене, тут не спорю. Но многое БД выражает сама. Согласованность состояния внутри строки - обычным CHECK (условно "если completed_at заполнен, score обязан быть не null"). Межстроковые правила вроде непересечения слотов преподавателя - через EXCLUDE обычный CHECK так не умеет, он видит одну строку. Вот про этот класс DDD-исты и говорят "единственный источник истины - домен, не дублируйте". Я считаю иначе: авторитетную проверку с человеческой ошибкой держу в домене, а констрейнт оставляю как фоллбек против гонок и записи в обход. Окей, тут дублирование и нужно поддерживать 2 места, но оно дешёвое. Как пример, в шве №3 это спасает от двойной записи в гонке.

У констрейнта есть минус - из БД прилетает голый код ошибки, без бизнес-контекста, его надо ловить и превращать во внятное сообщение.

Имхо, так это работает в связке норм.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации