Что такое архитектура ПО
Архитектура ПО — это совокупность фундаментальных решений о структуре системы, которые сложно или дорого менять после её реализации; она определяет компоненты системы, их взаимодействие и принципы, управляющие их эволюцией. Для системного аналитика архитектура служит инструментом анализа требований (разделение на стабильное ядро и изменчивые детали), языком коммуникации с разработчиками (обсуждение компонентов, связей и ограничений) и способом оценки рисков (понимание компромиссов между производительностью, надёжностью, масштабируемостью и стоимостью изменений). Ключевые элементы: архитектурные стили (монолит, микросервисы, EDA), качественные характеристики (нефункциональные требования), паттерны (Circuit Breaker, Saga, CQRS) и документирование решений через ADR (Architecture Decision Record).
Введение: Что скрывается за словами “архитектура ПО”
Когда говорят “архитектура ПО”, многие представляют схему с прямоугольниками и стрелками. Или думают, что это про выбор фреймворка или базы данных. На самом деле архитектура — это нечто другое.
Вот простое определение: архитектура программного обеспечения — это совокупность решений о том, как система устроена “под капотом”, которые сложно или дорого менять после того, как система уже работает.
Представьте, что вы строите дом. Архитектор решает, где будут несущие стены, где проходят коммуникации, где расположены лестницы. Поменять цвет обоев или переставить розетку — легко. А передвинуть несущую стену или перенести санузел на другой этаж — это почти снос и стройка заново. В программном обеспечении то же самое: архитектурные решения — это те, за которые вы платите потом долгие годы.
Для системного аналитика архитектура — это карта ограничений и возможностей. Вы не обязаны уметь спроектировать распределенную систему уровня Google. Но вы обязаны понимать: почему разработчики говорят “мы не можем добавить эту фичу без переписывания половины сервисов”, почему запросы стали тормозить после добавления новой функциональности, почему простая на первый взгляд задача требует двух месяцев работы.
Архитектура — это язык, на котором системный аналитик разговаривает с техническими лидами и архитекторами. Понимая архитектуру, вы можете:
- Оценивать реалистичность требований (“этот отчет потребует JOIN из трех разных сервисов — будет очень медленно”)
- Видеть риски на ранних этапах (“если мы добавим этот функционал, то сломаем изоляцию транзакций”)
- Участвовать в технических обсуждениях как равноправный партнер, а не как “передатчик требований”
Почему архитектура важна для системного аналитика
Разработчики работают с кодом. Архитекторы работают с компонентами и связями. А системный аналитик работает с тем, что находится между требованиями бизнеса и технической реализацией.
Представьте типичную ситуацию. Бизнес говорит: “Нам нужен отчет по продажам за последние три года с фильтрами по всем возможным параметрам”. Технически это может быть:
- Прямой запрос к операционной базе данных
- Отдельное хранилище данных (Data Warehouse) с предрасчитанными агрегатами
- Генерация отчета по запросу с кэшированием результатов
- Экспорт данных во внешнюю BI-систему
Каждый вариант — это разная архитектура. И системный аналитик должен понимать, какой вариант подходит для текущей ситуации. Не потому что вы пишете код. А потому что вы переводите бизнес-требования на язык ограничений: как часто нужен отчет, насколько свежие данные требуются, сколько пользователей будут его одновременно смотреть, какие фильтры реально нужны, а какие — “хотели бы, но не обязательно”.
Архитектура для аналитика — это инструмент мышления. Когда вы видите требование, вы автоматически начинаете думать: “Как это повлияет на базу данных? На сеть? На сервисы, с которыми это взаимодействует? На каком уровне лучше реализовать эту логику?”
Уровни архитектуры
Архитектуру принято рассматривать на разных уровнях детализации. Как географическая карта: есть карта мира, карта страны, карта города, план квартала.
Уровень системы (System Architecture) — это самое высокое описание. Как система взаимодействует с внешним миром: с пользователями, с другими системами, с аппаратным обеспечением. На этом уровне вы отвечаете на вопросы: сколько пользователей одновременно работают, какие каналы связи используются, какие внешние API вызываются, какие требования к безопасности.
Уровень приложения (Application Architecture) — описание того, как устроено само приложение. Из каких компонентов оно состоит, как эти компоненты взаимодействуют друг с другом. Здесь появляются сервисы, модули, базы данных, очереди сообщений. На этом уровне вы решаете: будет это монолит или микросервисы, как будет организовано хранение данных, как сервисы будут находить друг друга.
Уровень модуля (Module Architecture) — детализация внутри компонента. Какие классы или функции за что отвечают, как они обмениваются данными. Для аналитика этот уровень важен, когда нужно понять, почему изменение в одном месте ломает функциональность в другом.
Уровень кода (Code Architecture) — это уже про то, как написаны отдельные функции и методы. Стиль кодирования, паттерны проектирования, наименования переменных. На этом уровне аналитик обычно не работает, но понимание базовых паттернов помогает в коммуникации с разработчиками.
Для практической работы аналитику чаще всего нужны уровни системы и приложения. Вы должны уметь нарисовать схему того, как компоненты общаются друг с другом, и объяснить, почему они общаются именно так.
Архитектура как набор решений
Архитектура — это не про технологии. Это про решения, которые имеют долгосрочные последствия. И каждое архитектурное решение — это компромисс.
Возьмем простое решение: “мы храним историю изменений заказа”. Кажется, безобидно. Но это решение тянет за собой:
- Дополнительное место в базе данных (история растет)
- Дополнительное время на запись (нужно сохранить не только текущее состояние, но и изменения)
- Дополнительную сложность при чтении (какую версию показывать пользователю)
- Вопросы консистентности (что если два изменения произошли одновременно)
Или решение: “мы делаем микросервисы”. Это не просто “разделим код на несколько репозиториев”. Это решение определяет:
- Как будут общаться сервисы (синхронно через HTTP или асинхронно через очередь)
- Как обеспечивать согласованность данных между сервисами (двухфазный коммит? саги? event sourcing?)
- Как деплоить и масштабировать каждый сервис отдельно
- Какую дополнительную инфраструктуру нужно построить (сервис-дискавери, API gateway, распределенное трассирование)
Системный аналитик должен уметь раскладывать требования на архитектурные последствия. Когда бизнес просит “сделать отчет в реальном времени” — это не просто функциональное требование. Это архитектурное решение: скорее всего, вам понадобится отдельный сервис для обработки событий, потоковая обработка данных и отказ от строгой консистентности в пользу скорости.
Архитектурные характеристики (Quality Attributes)
Есть вещи, которые не входят в функциональные требования, но критически важны для архитектуры. Их называют качественными характеристиками, архитектурными качествами или не функциональными требованиями. Для системного аналитика это — основные точки контроля.
Производительность (Performance) — как быстро система отвечает на запросы. Измеряется в latency (время ответа на один запрос) и throughput (количество запросов в секунду). Архитектура влияет на производительность фундаментально: если данные размазаны по разным серверам, любой запрос, требующий их собрать вместе, будет медленным, как бы вы ни оптимизировали код.
Масштабируемость (Scalability) — как система ведет себя при росте нагрузки. Может ли она обслужить в два раза больше пользователей без изменения архитектуры? Или для этого нужно переписывать половину компонентов? Горизонтальное масштабирование (добавление серверов) требует другой архитектуры, чем вертикальное (увеличение мощности). И если архитектура не закладывает горизонтальное масштабирование с самого начала, добавить его потом будет очень больно.
Надежность (Reliability) — как часто система падает и как быстро восстанавливается. Архитектура определяет, есть ли единая точка отказа, как система ведет себя при падении одного из компонентов, возможна ли деградация (когда работает не все, но работает основное).
Сопровождаемость (Maintainability) — насколько легко менять систему. Это напрямую связано с архитектурной связностью: если компоненты сильно связаны, изменение в одном тянет изменения во всех остальных. Хорошая архитектура минимизирует связность и максимизирует связность внутри модуля.
Безопасность (Security) — архитектура определяет, где хранятся чувствительные данные, как они передаются, как происходит аутентификация и авторизация. Решение “сделать общую шину данных” может быть удобным, но оно создает одну точку, где можно перехватить все данные.
Доступность (Availability) — процент времени, когда система работает. Девяносто девять целых девять десятых процента (99.9%) — это около 8 часов простоя в год. Три девятки (99.99%) — это около 50 минут в год. Достижение высоких значений требует избыточности на всех уровнях, а это дорого.
Для каждого проекта эти характеристики имеют разный приоритет. Для платежной системы надежность и безопасность важнее всего, а производительность на втором месте. Для чата важна доступность и производительность, а строгая консистентность не обязательна. Системный аналитик должен уметь вместе с бизнесом расставить приоритеты и понять, чем можно пожертвовать.
Архитектурные стили как шаблоны решений
Архитектурные стили — это проверенные временем способы организации системы. Они не дают готового решения, но задают общую канву и правила игры.
Монолитная архитектура — вся логика приложения находится в одном развертываемом модуле. Это не значит “плохой код” или “одна большая функция”. Монолит может быть хорошо структурирован внутри, с четкими модулями и границами. Но деплоится и масштабируется он как единое целое. Для многих проектов это правильный выбор, особенно на старте.
Микросервисная архитектура — приложение разбито на множество маленьких независимых сервисов. Каждый сервис делает одну вещь и делает ее хорошо. Сервисы общаются через сеть, могут быть написаны на разных языках и масштабироваться независимо. Это звучит красиво, но плата за это — сложность распределенных систем.
Событийно-ориентированная архитектура (EDA) — сервисы общаются не напрямую, а через события. Один сервис публикует событие (“заказ оплачен”), другие сервисы подписываются на него и реагируют. Это дает слабую связанность, но усложняет понимание потока данных и отладку.
Луковая архитектура (Onion Architecture) и Clean Architecture — это способы организовать код внутри приложения, чтобы отделить бизнес-логику от внешних деталей (базы данных, API, пользовательского интерфейса). Главная идея: зависимости направлены внутрь. Бизнес-логика ничего не знает о том, как она вызвана или где хранит данные. Это делает систему более тестируемой и устойчивой к изменениям внешнего мира.
Понимание этих стилей позволяет аналитику задавать правильные вопросы. Если команда выбрала микросервисы, вы спрашиваете: “Как мы будем обеспечивать консистентность данных при сбоях? Какая у нас стратегия деплоя? Как мы будем отслеживать запрос, который проходит через пять сервисов?” Если монолит: “Как мы будем масштабировать критичные части? Как избежать того, что изменение в одном модуле ломает все приложение?”
Архитектурные паттерны
Если архитектурный стиль — это “крупный план” всей системы, то архитектурные паттерны — это решения для конкретных проблем, которые возникают внутри этого плана.
Например, Circuit Breaker решает проблему каскадных отказов: если сервис А вызывает сервис Б, а сервис Б начинает тормозить или падать, то запросы от А к Б начинают накапливаться и могут положить сервис А. Circuit Breaker отслеживает ошибки и “размыкает цепь” — перестает отправлять запросы к проблемному сервису, давая ему время восстановиться.
Saga Pattern решает проблему распределенных транзакций. В монолитной базе данных вы можете сделать ACID-транзакцию, которая обновит несколько таблиц атомарно. В микросервисах это невозможно. Saga разбивает операцию на последовательность локальных транзакций, каждая из которых обновляет данные в одном сервисе. Если что-то пошло не так, запускаются компенсирующие действия (отмена уже сделанного).
CQRS (Command Query Responsibility Segregation) разделяет операции изменения данных (команды) и операции чтения (запросы). Это может быть просто разделение на разные классы в коде, а может доходить до разных моделей данных и разных баз данных. Для запросов можно использовать денормализованные read-модели, оптимизированные под конкретные экраны. Для команд — нормализованную модель с гарантиями консистентности.
Strangler Fig Pattern описывает, как постепенно заменять старую систему на новую. Не переписывать все сразу (это почти всегда провал), а постепенно перехватывать запросы и перенаправлять их в новую систему. Старая система остается жить, пока не станет не нужна. Название от фикуса-душителя, который обвивает дерево-хозяина и постепенно его заменяет.
Системный аналитик не обязан знать все паттерны наизусть. Но когда вы слышите, как разработчики или архитекторы обсуждают эти термины, вы понимаете, о какой проблеме идет речь. И вы можете внести вклад: “А какая у нас стратегия отката в случае сбоя?” — это вопрос про Saga. “А что будет, если сервис авторизации упадет?” — это вопрос про Circuit Breaker.
Документирование архитектуры
Архитектура существует не только в головах архитекторов. Она должна быть задокументирована. Но документация архитектуры — это не “напишем 200 страниц, которые никто не прочитает”.
Для системного аналитика важны несколько типов артефактов.
Контекстная диаграмма (Context Diagram) показывает систему как черный ящик и ее взаимодействие с внешним миром: пользователи, внешние системы, аппаратное обеспечение. Это первое, что вы должны нарисовать для нового проекта. Она отвечает на вопрос: “Где границы нашей системы, а где — внешний мир?”
Диаграмма контейнеров (Container Diagram) показывает высокоуровневые компоненты системы: веб-приложение, мобильное приложение, база данных, очередь сообщений, кэш. Каждый контейнер — это нечто, что можно отдельно развернуть. Эта диаграмма отвечает на вопрос: “Из каких крупных частей состоит система и как они общаются?”
Диаграмма компонентов (Component Diagram) детализирует один контейнер. Показывает, из каких компонентов состоит, например, бэкенд-сервис. Компоненты — это логические группы кода (контроллеры, сервисы, репозитории). Эта диаграмма отвечает на вопрос: “Кто внутри контейнера с кем общается?”
Диаграмма последовательности (Sequence Diagram) показывает, как объекты или компоненты обмениваются сообщениями во времени. Это лучший способ объяснить сложный сценарий: “пользователь нажимает кнопку, система проверяет права, отправляет запрос в другой сервис, получает ответ, сохраняет в базу, возвращает результат”.
Для системного аналитика умение читать и создавать эти диаграммы — практический навык. Вы не должны рисовать их идеально по стандартам UML. Но вы должны уметь изобразить схему так, чтобы разработчики и архитекторы поняли, о чем вы говорите.
Архитектурные решения и их обоснование
Каждое архитектурное решение должно иметь обоснование. Не “мы используем PostgreSQL”, а “мы используем PostgreSQL, потому что нам нужны сложные JOIN, ACID-транзакции и полная поддержка внешних ключей, а объем данных пока позволяет одному серверу справляться с нагрузкой”.
Для системного аналитика сбор и документирование архитектурных решений — важная часть работы. Когда через полгода кто-то спросит “а почему у нас нет шардирования?”, вы сможете ответить: “потому что на момент проектирования мы ожидали 100 тысяч пользователей, а не 10 миллионов, и решение было экономически обосновано. Сейчас условия изменились, и мы планируем переход на шардирование в следующем квартале”.
ADR (Architecture Decision Record) — это формат документирования архитектурных решений. Один ADR описывает одно решение: контекст, в котором оно принималось, рассмотренные альтернативы, само решение и его последствия. ADR хранятся рядом с кодом в репозитории и живут вместе с проектом.
Структура ADR:
- Заголовок — краткое название решения
- Статус — предложено, принято, устарело, заменено
- Контекст — почему мы вообще рассматриваем это решение, какие у нас ограничения
- Рассмотренные альтернативы — что еще мы могли сделать и почему не выбрали
- Решение — что мы выбрали и как это будет работать
- Последствия — что становится проще, что сложнее, какие новые проблемы появляются
Системный аналитик часто участвует в создании ADR: описывает контекст с точки зрения требований, помогает формулировать последствия для бизнес-логики, проверяет, что решение соответствует нефункциональным требованиям.
Архитектура и требования: как они связаны
Архитектура не существует сама по себе. Она рождается из требований и ограничений. И системный аналитик — тот человек, который соединяет эти два мира.
Функциональные требования определяют, что система должна делать. Из них рождаются компоненты и их обязанности. “Пользователь может оформить заказ” — это требование, которое определит компонент “Корзина”, “Заказ”, “Платеж”, “Уведомление”.
Нефункциональные требования определяют, как хорошо система должна это делать. И именно они чаще всего определяют архитектурные стили и паттерны. “Время оформления заказа не должно превышать 2 секунд при 1000 одновременных пользователей” — это требование может привести к выбору асинхронной обработки, кэширования и репликации базы данных.
Ограничения — это то, что нельзя изменить или очень дорого изменить. Бюджет, сроки, существующие системы, навыки команды, регуляторные требования. Ограничения часто являются главными драйверами архитектурных решений. “У нас нет денег на облако, будем держать сервера в своем дата-центре” — это ограничение, которое определит архитектуру на годы вперед.
Системный аналитик должен уметь выявлять архитектурно-значимые требования. Не все требования влияют на архитектуру. “Изменить цвет кнопки” не влияет. “Добавить историю изменений заказа” — влияет. “Увеличить время сессии с 30 минут до часа” — скорее всего, не влияет. “Добавить возможность входа через Google” — влияет, потому что добавляет внешний API и вопросы безопасности.
Анализ архитектурных рисков
Архитектурные решения — это инвестиции. Вы вкладываете сложность сегодня, чтобы получить гибкость или производительность завтра. Но иногда инвестиции не окупаются. Системный аналитик должен уметь видеть риски в архитектуре.
Риск преждевременной оптимизации — когда архитектура усложняется под нагрузку, которой пока нет. Микросервисы для прототипа на 10 пользователей — это риск. Вы тратите время на распределенные транзакции, хотя могли бы обойтись одним монолитом и сэкономить месяцы разработки.
Риск технологической несовместимости — когда архитектура требует технологии, которую команда не знает или которая не вписывается в существующий ландшафт. “Давайте писать сервис на Rust” в команде Java-разработчиков — это риск.
Риск скрытой сложности — когда архитектура кажется простой, но скрывает сложность в деталях. Синхронный HTTP между сервисами выглядит просто. Но что будет с задержками? С ретраями? С частичными отказами? С версионированием API?
Риск необратимости — некоторые архитектурные решения невозможно отменить без переписывания системы. Если вы спроектировали данные под конкретный ключ шардирования, изменить его — это миграция всех данных. Если вы построили систему на событийной модели, перейти на синхронные вызовы будет очень сложно.
Системный аналитик не должен паниковать от каждого риска. Но он должен их документировать и поднимать на обсуждение. “Мы понимаем, что выбор шардирования по user_id означает, что отчеты по заказам без привязки к пользователю будут очень медленными. Это соответствует ожиданиям бизнеса или нет?”
Архитектура как язык коммуникации
Самое важное, что нужно понять системному аналитику об архитектуре: это не про код, это про коммуникацию.
Когда вы говорите “у нас монолит”, все понимают: деплой раз в неделю, масштабирование целиком, проще отладка, сложнее изолировать ошибки. Когда вы говорите “у нас микросервисы”, все понимают: сложность распределенных транзакций, нужно API gateway, нужны инструменты observability, независимый деплой.
Архитектура — это общее понимание того, как система устроена и как она будет развиваться. Системный аналитик — один из хранителей этого понимания. Вы не обязаны принимать архитектурные решения. Но вы обязаны их понимать, задавать вопросы, видеть несоответствия между требованиями и архитектурой.
Если бизнес просит “добавить возможность отмены заказа через 5 минут после оплаты”, вы должны подумать не только о кнопке в интерфейсе. Вы должны подумать: “А наша платежная система поддерживает отмену? А у нас вообще есть способ связаться с банком после того, как транзакция прошла? А что будет с заказом, который уже отправили на сборку?” И эти вопросы — не про код, а про архитектуру.
Резюме
Архитектура ПО — это не про выбор фреймворка или базы данных. Это про долгосрочные решения, которые определяют, как система будет расти, меняться и выдерживать нагрузки.
Для системного аналитика архитектура — это:
- Инструмент анализа требований: вы видите не только “что” нужно сделать, но и “как” это повлияет на систему
- Язык коммуникации с разработчиками и архитекторами: вы говорите на одном языке о компонентах, связях и ограничениях
- Способ оценки рисков: вы понимаете, какие решения обратимы, а какие — нет
- Карта компромиссов: вы знаете, что за каждое преимущество приходится платить