теория
Почему компоненты вообще приходится менять вместе? Причин ровно две — и, к счастью, их легко удержать в голове.
1. Общий жизненный цикл (). Модули одного монолита тестируются, деплоятся и сопровождаются вместе — даже если друг про друга слыхом не слыхивали. Вынеси их в отдельные сервисы — и эта связь ослабнет: каждый заживёт своим релизным ритмом.
2. Общее знание (). Чем больше один компонент знает про другой, тем больше у них общих поводов меняться. Посмотри, как это работает на простом примере — доступе к данным:
| Интерфейс | Какое знание утекает |
|---|---|
MySQLRepository | конкретная СУБД: сменил MySQL — сломал потребителя |
IRepository.ExecuteSQL() | семейство СУБД: «внутри что-то реляционное» |
IRepository.Save() / Query() | только минимум, нужный для работы |
Одна и та же функциональность — три очень разных объёма общего знания. Чем меньше его пересекает границу, тем реже прилетают .
А самое коварное — : предположения, которые нигде не записаны. Выгрузка «знала» схему чужой таблицы. Код «знает», что сервер в UTC, что файл лежит вон там, что заказы никогда не удаляются. Такие связи не видно — пока они не порвутся в самый неподходящий момент.
Вот и весь фокус: coupling — не то, с чем сражаются, а то, что проектируют. Случайные связи — убирать. Существенным — осознанно отмерять, сколько знания им позволено переносить.