Как мы справлялись с версиями, контрактами и сопротивлением

Продолжаем разбирать сложности модуляризации (STAR, первые сложности) на примере команды Незнайки и нашего опыта.

Синхронизация версий: дилемма, которая ломает релизы

Когда модули развиваются независимо, легко получить несовместимые версии зависимостей. В мобильной разработке это особенно остро: в отличие от десктопа, где можно подключить разные версии DLL, здесь нет «из коробки» механизма одновременной поддержки двух несовместимых версий пакетов.

Команда Незнайки выбрала простой, но болезненный путь: обновлять всех клиентов разом до новой версии зависимости. Результат — огромные перегрузки при нарушении старых контрактов.

Мы пошли другим путём: 1. Минимизировали нарушения контрактов, глубоко внедряя принцип Open/Closed. 2. Поддерживали одновременно старый и новый контракты. Это позволило обновлять потребителей постепенно, без спешки и перегрузки, по заранее проработанному плану.

Такой подход дал нам гибкость: мы не зависели от того, когда каждая команда будет готова к обновлению.

Но тут важно не уйти в другую крайность. Если бесконечно сохранять старые контракты, их накопится столько, что поддерживать станет невозможно. Поэтому мы ввели жёсткое правило: одновременно может существовать не более двух версий контракта. Если нужно внести новые изменения — сначала все потребители должны быть переведены на самую свежую из текущих версий. И только после этого мы выпускаем следующую версию контракта и вносим изменения. Такой подход не даёт экосистеме обрастать наследием и сохраняет управляемость.

Обучение команды и сопротивление изменениям

Как было обозначено в предыдущем посте, разработчикам помимо самой модуляризации нужно освоить: новые подходы к проектированию и базовые принципы (Low coupling/High cohesion, Single Responsibility и т.д.), инструменты сборки модульных систем, шаблонизацию и т.д.

Обучить сотрудника, который уже считает себя гуру, – крайне непростой процесс. Мы обязательно поговорим о нем (процессе обучения "гуру") когда-нибудь в будущем. Пока же я сам все еще формулирую для себя все проблемы обучения программистов лучшим практикам.

Команда может сопротивляться переходу из‑за страха перед каждой из описанных сложностей или необходимости переучиваться. О работе с изменениями и с сопротивлением изменениями написано очень много хороших книг. Возможно, чуть более подробнее мы поговорим об этом в будущих постах про обучение команды.

Временное снижение продуктивности

На этапе перехода скорость разработки обычно падает. Если разработчики не знакомы с тем, как справляться с описанными сложностями, то, скорее всего, скорость разработки больше никогда и не повысится. Бизнес готов терпеть временное снижение продуктивности, но только если в будущем это приведет к её постоянному повышению. Разработчики подсознательно это понимают, а потому очень сопротивляются таким изменениям.

Ключевые уроки

История Незнайки — классический пример, как недооценка фундаментальных принципов и человеческого фактора превращает хорошую идею в проблему. Главные выводы: 1. Границы модулей — не формальность. Нечёткое разделение делает модуляризацию бессмысленной: связи остаются, стоимость растёт, пользы нет. 2. Granularity matters. Слишком мелкие модули — это лишние накладные расходы, а не «продвинутость». 3. Автоматизация — необходимость. Без шаблонизации и DevOps мультирепозиторий съедает ресурсы быстрее, чем приносит пользу. 4. Люди важнее архитектуры. Сопротивление и нехватка обучения могут похоронить даже самую грамотную схему. 5. Open/Closed — ваш лучший друг. Он спасает от каскадных обновлений и позволяет эволюционировать постепенно.

Помните: модуляризация — не цель, а инструмент. Её смысл — снизить сложность, а не создать новую.

С какими проблемами модуляризации сталкивались именно вы? О решении какой из них хотели бы прочитать подробнее? Пишите в комментариях.

В следующем посте продолжим тему эффективного производства. Не переключайтесь! 🔥