теория
Полгода назад команда выучила: связь — это знание, пересекающее границу. Инцидент добавляет вопрос: какое именно знание? От ответа зависит — то, останется ли изменение внутри модуля или каскадом пройдёт по всей системе.
Идее больше полувека: ещё в структурном дизайне конца 1960-х была шкала из шести уровней — от «лезем в чужие потроха» до «передаём голый минимум данных». Мы возьмём её современную версию: четыре уровня по типу знания, текущего через границу.
| Уровень | Какое знание делится | В «Ярмарке» |
|---|---|---|
| — интрузивная | детали реализации, не предназначенные для интеграции | Отчёты, читавшие order_discounts напрямую (акт I) |
| — функциональная | бизнес-правила, инварианты, порядок действий | формула скидки, повторённая в Доставке; сверка сумм в Платежах |
| — модельная | доменная модель данных | найдём через минуту в Заказах |
| — контрактная | интеграционная модель, спроектированная для потребителей | ReportsGateway: только то, что нужно отчётам |
Intrusive — сильнейший уровень: downstream зависит от того, что автор вообще не считал интерфейсом. Любое изменение upstream может сломать интеграцию — и автор об этом даже не узнает. «Ярмарка» вылечила такую связь ещё в первом акте, не зная её имени.
Functional — модули разделяют не данные, а поведение: одно правило, один инвариант, один сценарий. Здесь нет upstream и downstream — знание принадлежит обоим сразу, и меняться они обязаны одновременно.
Model — наружу отдана собственная доменная модель (внутреннее устройство данных модуля: его таблицы, классы, связи). Данные стабильнее логики, поэтому каскады реже, но каждый рефакторинг модели теперь согласуется со всеми потребителями.
Contract — слабейший уровень: наружу выставлена специальная модель для интеграции, «модель модели». Даже самый развесистый контракт делит меньше знания, чем самая скромная доменная модель: он не привязан к устройству владельца и может версионироваться.
Шкала объясняет вчерашний вечер. «Все ходят через API» — правда про транспорт, а не про знание: по одним API течёт контракт, по другим — чужая модель, а самая сильная связь обошлась вообще без API.