Модульный монолит

Базовый System Design
≈ 2 мин чтения

Один процесс, но явные границы внутри

Модульный монолит сохраняет единое развёртывание, но делит приложение на крупные функциональные модули. Каждый модуль отвечает за свою область и предоставляет другим частям системы небольшой публичный интерфейс, вместо свободного доступа к любому внутреннему классу.

Monolith
|-- Orders ---- public API
|-- Payments -- public API
`-- Users ----- public API

Такое устройство уменьшает связанность ещё до появления сети. Команда может менять реализацию модуля, не заставляя остальное приложение знать его внутренние таблицы, классы и детали алгоритмов.

Граница должна защищаться кодом

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

При этом модули всё ещё работают в одном процессе, поэтому взаимодействие остаётся быстрым, а эксплуатация — значительно проще, чем у набора независимых сервисов.

Почему это важный промежуточный вариант

Модульный монолит позволяет проверить границы предметных областей без стоимости распределённой системы. Если позже один модуль действительно потребуется выделить в отдельный сервис, уже существующий интерфейс и ограниченные зависимости сильно упрощают такое изменение.

Сначала границы, потом процессы. Если части системы невозможно изолировать внутри одного приложения, перенос их в разные сервисы обычно не устраняет связанность — он лишь делает её сетевой.