Выбирай архитектурные границы по конкретным причинам изменения и отказа. Разбери направление зависимостей, монолит и микросервисы, сетевые контракты, распределённые гарантии и ход системного дизайна от требований к узким местам.
Организуй код так, чтобы доменная логика зависела от нужных ей контрактов, а конкретные адаптеры собирались у границы приложения. Проверь интерфейсы, ошибки, конфиг и размер пакетов на реальные причины изменения, а не на названия архитектурных стилей.
Сравни монолит и микросервисы по командам, независимому выпуску, масштабированию и отказам. Перед распилом проверь, можно ли провести модульные границы внутри одного процесса и какие сетевые обязанности появятся у каждого нового сервиса.
Разбери, почему транзакция не пересекает процессную границу, и выбери синхронный вызов, outbox/inbox, сагу или событие по требованиям сценария. Пойми, где подтверждение может потеряться, какие шаги повторятся и как сохранить совместимость схемы сообщения.
Исходи из того, что сеть задерживает ответы, часы расходятся, а узлы падают между шагами. Применяй идемпотентность, deadline, jitter, bulkhead и fencing token, затем различай CAP выбор при partition и компромисс latency/consistency в обычной работе.
Веди системный дизайн от требований к модели данных, API, нагрузке, архитектуре и отказам. На каждом шаге фиксируй допущение и решение, а затем проверяй, какое ограничение первым нарушит цель при заданном росте.