Архитектура ПО: проектирование и планирование до первой строки кода
Самое дорогое, что можно сделать в разработке, — написать много кода, а потом выяснить, что система устроена не так, как нужно. Исправить фундамент в готовом здании дороже, чем сделать его правильно. Поэтому в любом проекте, будь то промышленная платформа или внутренний сервис, я начинаю с архитектуры. Это часть общего процесса, который описан в статье Разработка ПО с нуля под ключ: от идеи до релиза.
Что такое архитектура и зачем она нужна
Архитектура — это набор ключевых решений о системе, которые трудно изменить позже: из каких частей она состоит, как они общаются, где хранятся данные, как система разворачивается и как защищена. Мелкие решения (имена функций, внутренности модуля) можно поменять за день. Решения вроде «одна база или несколько» или «монолит или сервисы» меняются месяцами.
Хорошая архитектура даёт заказчику практические вещи:
- предсказуемые сроки и бюджет — понятно, из чего складывается работа;
- возможность развивать систему — новые функции добавляются без переписывания;
- меньше ошибок — границы модулей не дают проблемам расползаться;
- безопасность по замыслу — защита закладывается в структуру, о чём подробнее в статье Безопасная разработка ПО: как защита закладывается с первого дня;
- независимость от автора — решения записаны, и проект сможет подхватить другой инженер.
Шаг 1. Требования: функциональные и нефункциональные
Прежде чем рисовать схемы, нужно понять, что именно строим. Я разделяю требования на две части.
Функциональные: что система делает, кто с ней работает, какие у неё роли и сценарии.
Нефункциональные, которые чаще всего определяют архитектуру:
| Группа | Вопросы |
|---|---|
| Нагрузка | Сколько пользователей, сколько данных, какой поток в секунду? |
| Надёжность | Что будет при отказе сервера? Можно ли терять данные? |
| Безопасность | Кто что не должен видеть? Какие данные персональные? |
| Среда | Облако, свои серверы, закрытая сеть без интернета? |
| Сопровождение | Кто будет развёртывать и обновлять? |
| Ограничения | Бюджет, сроки, обязательные технологии, требования регуляторов |
Например, для «Русло»: как строится IIoT-платформа для закрытой сети предприятия решающими стали два требования: поток телеметрии и работа без интернета. Они определили выбор ClickHouse и отказ от облачных зависимостей. Для Keel: как спроектировать систему, в которой нельзя подсмотреть решило требование обезличивания: оно определило структуру баз данных.
Шаг 2. Ключевые решения и их запись
Для каждого значимого решения я фиксирую его в коротком документе, который называется ADR (Architecture Decision Record):
- Контекст — какая проблема решается и какие ограничения.
- Варианты — что рассматривали.
- Решение — что выбрали.
- Последствия — что получили и чем заплатили.
Такая запись нужна по двум причинам. Во-первых, она заставляет меня проверить выбор, а не положиться на привычку. Во-вторых, через год вам не придётся гадать, почему система устроена именно так. Привычка обосновывать решения пришла ко мне из судебной практики: вывод без обоснования там не принимают. Подробнее — в статье Кто такой craftzman: от судебного эксперта до архитектора.
Шаг 3. Границы и структура системы
Дальше определяю, из каких частей состоит система. Вопросы, которые я задаю:
- Монолит или сервисы? Для небольшой команды и понятной предметной области аккуратный модульный монолит часто выигрывает. Сервисы нужны, когда части системы нужно масштабировать и развёртывать независимо. В проекте FlameApp мы разделяли монолит на микросервисы с Kafka и RabbitMQ именно потому, что для этого были причины.
- Где проходят границы данных? Кто владеет данными и кто имеет право их менять.
- Как части общаются? Синхронные вызовы, очереди, события.
- Что можно заменить? Внешние зависимости прячу за интерфейсами, чтобы смена поставщика не ломала систему.
Результат — понятная схема на нескольких уровнях детализации: контекст (система и её окружение), контейнеры (приложения и хранилища), компоненты (модули внутри).
Шаг 4. Выбор технологий
Технологии выбираю под требования, а не из любви к новому. Критерии: зрелость, поддержка, доступность специалистов, соответствие нагрузке и среде. Если задача требует надёжности и работы без сбоев годами, подойдёт Rust. Для корпоративных интеграций часто хороши Java и Spring Boot. Для быстрого API — Node.js. Ничего «универсально лучшего» нет, и я не навязываю свои предпочтения.
Шаг 5. Декомпозиция и планирование
Когда структура ясна, система разбивается на задачи. Правила, которые я соблюдаю:
- задача не больше нескольких дней работы и имеет проверяемый критерий готовности;
- первыми идут задачи, которые снимают самые большие риски (интеграции, нагрузка, сложные правила доступа);
- рано собирается «сквозной» сценарий: от интерфейса до базы, чтобы проверить, что части стыкуются;
- в плане отдельно учтены тесты, документация и развёртывание, а не «как получится».
Вы получаете этапы с понятными результатами. После каждого этапа можно остановиться, посмотреть, что получилось, и скорректировать курс.
Шаг 6. Риски и план Б
Для каждого заметного риска записываю, что его вызывает, насколько он вероятен и что делать. Например: «интеграция с внешним сервисом нестабильна — тогда добавляем очередь и повторные попытки». Лучше обсудить это заранее, чем в день сдачи.
Типичные ошибки, которых позволяет избежать архитектура
- Разработка начинается без нефункциональных требований, и в последний момент оказывается, что система не выдерживает нагрузку.
- Безопасность откладывается на конец, и её приходится вшивать в готовое решение.
- Все части связаны со всеми, и любое изменение ломает десять мест.
- Решения нигде не записаны и живут в голове одного человека.
Нужна архитектура для вашего продукта?
Я могу выполнить проектирование отдельно (как самостоятельную услугу) или в составе полной разработки. В результате вы получите схему системы, выбранный стек с обоснованием, список рисков и план работ. Напишите мне: Telegram @w1shmaster. Как дальше строится код, расскажут статьи про Качество кода: что оно значит для бизнеса и как его обеспечить и Тестирование и приёмка ПО: как убедиться, что система работает до релиза.