4.04. Основы архитектуры
Разработчику
Аналитику
Тестировщику
Архитектору
Инженеру
Основы архитектуры
Архитектура программного обеспечения — это фундамент, на котором строится любое приложение. Она определяет, как устроена система, из каких частей она состоит, как эти части взаимодействуют между собой и как они будут развиваться со временем.
Что такое архитектура ПО
Архитектура программного обеспечения — это совокупность структурных решений, принятых на ранних этапах проектирования системы, которые определяют её состав, организацию компонентов, их взаимосвязи и принципы взаимодействия.
Архитектура отвечает на вопросы:
- Какие части есть в системе?
- Как они связаны?
- Как данные перемещаются между ними?
- Как система будет масштабироваться?
- Какие технологии использовать?
- Как обеспечить надёжность, безопасность и удобство сопровождения?
Архитектура — это то, что остаётся, когда убирают все детали реализации. Это уровень абстракции, позволяющий говорить о системе в целом, не погружаясь в строки кода.
Разработчику-самоучке будет сложно понять, насколько это невероятно огромная область информационных технологий, но требуется много читать, чтобы быть опытным.
Компоненты программного обеспечения
Любая система состоит из компонентов — логически или физически обособленных частей, выполняющих определённую функцию. Компоненты могут быть:
- Модулями — наборами классов, функций и ресурсов, объединённых общей задачей (например, модуль авторизации, модуль оплаты).
- Классами — базовыми строительными блоками в объектно-ориентированных языках. Каждый класс инкапсулирует данные и поведение.
- Базами данных — хранилищами структурированной информации. Они могут быть реляционными (PostgreSQL, MySQL), документными (MongoDB) или другими.
- Сервисами — независимыми исполняемыми единицами, предоставляющими функциональность через интерфейсы (API).
- Интерфейсами пользователя — частями системы, с которыми взаимодействует человек (веб-страницы, мобильные экраны, десктопные окна).
Компоненты не существуют изолированно. Они взаимодействуют друг с другом, образуя сложную сеть зависимостей и потоков данных.
Связи между компонентами
Связи определяют, как компоненты обмениваются информацией. Существуют два основных типа связей:
- Синхронные — вызов одного компонента немедленно ожидает ответа от другого (например, HTTP-запрос к API).
- Асинхронные — компонент отправляет сообщение и продолжает работу, не дожидаясь ответа (например, отправка события в очередь сообщений).
Связи могут быть:
- Жёсткими — компонент напрямую зависит от конкретной реализации другого.
- Гибкими — компонент взаимодействует через интерфейс или контракт, что позволяет заменять реализации без переписывания кода.
Хорошая архитектура стремится к слабой связанности — минимальной зависимости между компонентами, чтобы изменения в одном месте не ломали другие.
Принципы развития системы
Архитектура должна поддерживать эволюцию. Система растёт: добавляются новые функции, меняются требования, появляются новые пользователи. Поэтому архитектура строится с учётом:
- Масштабируемости — способности системы расти под нагрузкой.
- Поддерживаемости — лёгкости внесения изменений и исправления ошибок.
- Тестируемости — возможности проверить каждую часть независимо.
- Разделяемости ответственности — каждый компонент делает одну вещь и делает её хорошо.
Эти принципы воплощаются в таких подходах, как SOLID, DRY, KISS, YAGNI, которые помогают писать чистый и гибкий код.
Как проектируют ПО
Проектирование начинается с анализа требований. Аналитик собирает информацию от заказчика, пользователей, бизнеса. Затем архитектор:
- Определяет границы системы — что входит, а что нет.
- Выделяет основные компоненты и их роли.
- Выбирает архитектурный стиль (монолит, микросервисы, слоистая и т.д.).
- Продумывает потоки данных и точки интеграции.
- Формирует архитектурное описание — документ, содержащий диаграммы, решения, ограничения.
Проектирование — это итеративный процесс. Архитектор может создавать несколько вариантов, сравнивать их по критериям (стоимость, сложность, риски) и выбирать оптимальный.
Роль архитектора
Архитектор ПО — это технический лидер, который видит систему целиком. Он:
- Принимает ключевые технические решения.
- Обеспечивает соответствие архитектуры бизнес-целям.
- Консультирует разработчиков и аналитиков.
- Следит за соблюдением архитектурных принципов.
- Участвует в оценке рисков и планировании релизов.
Архитектор не пишет весь код, но он задаёт правила игры, по которым команда создаёт продукт.
Как выглядят сложные системы
Сложная система — это не просто большой код. Это организованная структура, где:
- Есть логические уровни: представление (UI), бизнес-логика, доступ к данным.
- Есть физические уровни: клиентское устройство, веб-сервер, база данных, облачные сервисы.
- Есть механизмы взаимодействия: REST API, очереди сообщений, gRPC, GraphQL.
- Есть инфраструктурные элементы: балансировщики нагрузки, кэши, мониторинг, логирование.
Например, интернет-магазин может включать:
- Фронтенд (React/Vue)
- Бэкенд-сервисы (каталог, корзина, оплата)
- Базу данных PostgreSQL
- Систему уведомлений через RabbitMQ
- Микросервис рекомендаций на Python
- CDN для раздачи изображений
Всё это работает как единый организм благодаря продуманной архитектуре.
Как аналитики работают с архитектурой
Аналитик получает от архитектора архитектурное описание — карту системы. На её основе он:
- Декомпозирует общие задачи на конкретные пользовательские истории.
- Определяет, какие компоненты затрагивает каждая функция.
- Уточняет интерфейсы взаимодействия между модулями.
- Формирует спецификации требований для разработчиков.
Например, если архитектор решил, что оплата будет вынесена в отдельный микросервис, аналитик пропишет, как фронтенд должен вызывать этот сервис, какие данные передавать, как обрабатывать ошибки.
Как разработчики реализуют архитектуру
Разработчик получает техническое задание, основанное на архитектуре. Он:
- Создаёт модули и классы в соответствии с выделенными границами.
- Реализует интерфейсы взаимодействия (API, DTO, события).
- Соблюдает принципы проектирования, заданные архитектором.
- Пишет тесты, проверяющие корректность работы компонента в системе.
Разработчик не решает, «куда положить логику оплаты» — это уже решено на архитектурном уровне. Его задача — качественно реализовать задуманное.
Монолит и микросервисы — вкратце
Монолит — это единое приложение, где все компоненты (UI, логика, БД) собраны в один исполняемый файл или процесс. Преимущества: простота развёртывания, отладки, тестирования. Недостатки: сложно масштабировать отдельные части, риск «разрастания» кодовой базы.
Микросервисы — это набор независимых сервисов, каждый из которых отвечает за свою бизнес-функцию. Преимущества: гибкость, независимое развёртывание, масштабируемость. Недостатки: сложность управления, сетевые задержки, необходимость координации данных.
Выбор между ними зависит от масштаба проекта, команды, требований к надёжности и скорости разработки.
Слоистая архитектура
Слоистая (или многоуровневая) архитектура — один из самых распространённых стилей. Система делится на логические слои, каждый из которых имеет чёткую ответственность:
- Презентационный слой (Presentation) — отвечает за отображение данных и взаимодействие с пользователем.
- Слой бизнес-логики (Business Logic) — содержит правила, алгоритмы, процессы.
- Слой доступа к данным (Data Access) — управляет чтением и записью в хранилища.
Слои взаимодействуют только с соседними: презентация вызывает логику, логика — доступ к данным. Это упрощает тестирование и замену компонентов.
Логические и физические уровни
- Логические уровни — это абстракции внутри кода (слои, модули, пакеты). Они помогают организовать мышление разработчика.
- Физические уровни — это реальные машины, контейнеры, процессы, на которых запускаются части системы.
Например, логический слой «бизнес-логика» может быть развёрнут на нескольких серверах (физических уровнях) для обеспечения отказоустойчивости.
Проектное решение
Проектное решение — это конкретный выбор, сделанный в рамках архитектуры. Например:
- Использовать PostgreSQL вместо MySQL.
- Хранить файлы в MinIO, а не на диске сервера.
- Реализовать авторизацию через OAuth 2.0.
- Разделить модуль отчётов на отдельный микросервис.
Каждое проектное решение документируется, обосновывается и становится частью архитектурного описания.
Коннекторы и способы взаимодействия
Коннекторы — это механизмы, через которые компоненты обмениваются данными. Они определяют:
- Протокол (HTTP, TCP, AMQP)
- Формат данных (JSON, XML, Protobuf)
- Метод вызова (REST, SOAP, RPC)
- Гарантии доставки (at-least-once, exactly-once)
Выбор коннектора влияет на производительность, надёжность и сложность системы.
Декомпозиция и объединение модулей
Декомпозиция — это разбиение большой задачи на маленькие модули. Цель — сделать каждый модуль:
- Понятным
- Тестируемым
- Переиспользуемым
Объединение происходит, когда модули работают вместе для выполнения сложной функции. Например, оформление заказа объединяет модули корзины, каталога, оплаты и доставки.
Правильная декомпозиция — ключ к поддерживаемой архитектуре.
Развертывание и внедрение
Развёртывание — это процесс установки системы на серверы или в облако. Архитектура определяет:
- Сколько экземпляров каждого компонента нужно запустить.
- Как они будут обновляться (blue-green, канареечные релизы).
- Как обеспечить отказоустойчивость.
Внедрение — это передача системы в эксплуатацию: обучение пользователей, настройка мониторинга, подготовка документации.
Процессный, параллельный и клиент-серверный обмен
- Процессный обмен — данные передаются в рамках одного процесса (вызов метода, передача объекта).
- Параллельный обмен — несколько потоков или процессов работают одновременно, используя общие ресурсы (очереди, блокировки).
- Клиент-серверный обмен — один компонент (клиент) запрашивает данные у другого (сервера) по сети.
Архитектура выбирает подход в зависимости от требований к производительности, изоляции и распределённости.
Архитектурный шаблон (паттерн)
Архитектурный паттерн — это проверенное решение типовой проблемы. Примеры:
- MVC — разделение на модель, представление, контроллер.
- CQRS — разделение команд и запросов.
- Event Sourcing — хранение истории изменений вместо текущего состояния.
- Strangler Fig — постепенная замена монолита микросервисами.
Паттерны — не догма, а инструменты. Их можно комбинировать и адаптировать.
Архитектурное описание и его элементы
Архитектурное описание — это документ, содержащий:
- Архитектурные группы описаний — логические разделы (например, «инфраструктура», «безопасность», «интеграции»).
- Виды моделей — диаграммы компонентов, развёртывания, последовательностей.
- Функциональную архитектуру — что система делает.
- Поведенческую архитектуру — как она реагирует на события.
- Временную архитектуру — как компоненты взаимодействуют во времени (тайминги, задержки, TTL).
Это живой документ, который обновляется по мере развития системы.
Архитектурный подход и метод описания
Архитектурный подход — это философия проектирования:
- «Сначала масштабируемость»
- «Максимальная простота»
- «Безопасность превыше всего»
Метод описания — это способ фиксации архитектуры:
- Диаграммы UML
- C4-модель
- ADR (Architectural Decision Records)
- Простые текстовые документы с пояснениями
Выбор метода зависит от культуры команды и сложности проекта.
Функциональная, поведенческая и временная архитектура
Архитектура программного обеспечения рассматривается с разных точек зрения. Это позволяет охватить все аспекты системы: что она делает, как реагирует на события и как ведёт себя во времени.
Функциональная архитектура
Функциональная архитектура описывает, что система делает. Она фокусируется на бизнес-функциях, операциях и сервисах, которые предоставляет приложение. В этой модели:
- Выделяются основные функциональные блоки (например, «управление пользователями», «обработка заказов»).
- Определяются входы и выходы каждого блока.
- Указываются зависимости между функциями.
Функциональная архитектура часто используется аналитиками и бизнес-заказчиками, так как она говорит на языке задач, а не технических деталей.
Пример: в интернет-магазине функциональная архитектура может включать:
- Каталог товаров
- Корзина покупок
- Система оплаты
- Личный кабинет
- Уведомления
Каждая из этих функций чётко определена по своему назначению и интерфейсу.
Поведенческая архитектура
Поведенческая архитектура описывает, как система реагирует на внешние и внутренние события. Она фокусируется на динамике: последовательностях действий, состояниях компонентов, реакциях на ошибки.
Эта архитектура отвечает на вопросы:
- Что происходит, когда пользователь нажимает «Оформить заказ»?
- Как система обрабатывает отказ платёжного шлюза?
- Какие шаги выполняются при регистрации нового пользователя?
Для описания поведенческой архитектуры используются:
- Диаграммы последовательностей (sequence diagrams)
- Диаграммы состояний (state machines)
- Диаграммы активности (activity diagrams)
Поведенческая модель особенно важна для разработчиков и тестировщиков, так как она показывает логику выполнения.
Временная архитектура
Временная архитектура описывает, как система ведёт себя во времени: задержки, тайминги, TTL (время жизни данных), периодичность задач, время отклика.
Эта архитектура учитывает:
- Сколько времени занимает обработка запроса.
- Как часто запускаются фоновые задачи (например, ежедневная рассылка).
- Сколько времени данные хранятся в кэше.
- Как система реагирует на пиковые нагрузки.
Временная архитектура критична для систем реального времени, финансовых приложений, IoT-устройств, где задержки могут привести к сбоям или убыткам.
Пример: в системе мониторинга датчиков температуры:
- Данные с датчика отправляются каждые 5 секунд.
- Если за 15 секунд нет сигнала — система генерирует аварию.
- Агрегированные данные сохраняются на 30 дней.
Такие временные параметры становятся частью архитектурного контракта.
Архитектурные группы описаний и виды моделей
Архитектура не описывается одним документом. Она состоит из архитектурных групп описаний — логически связанных наборов информации, ориентированных на разные аудитории:
- Структурная группа — компоненты, модули, зависимости.
- Поведенческая группа — сценарии, потоки, реакции.
- Развёртывания — физические серверы, контейнеры, сети.
- Безопасности — точки контроля доступа, шифрование, аудит.
- Производительности — ограничения по времени, пропускной способности.
Каждая группа содержит виды моделей:
- Логическая модель — абстрактное представление без привязки к технологии.
- Физическая модель — конкретные серверы, базы данных, облачные сервисы.
- Концептуальная модель — высокоуровневое видение для заказчика.
- Имплементационная модель — детали для разработчиков.
Хорошая архитектура покрывает все эти виды, чтобы каждый участник проекта получил нужную информацию.
Архитектурный подход и метод описания
Архитектурный подход — это философия, которой следует команда. Например:
- «Сначала безопасность» — все решения проверяются на соответствие требованиям безопасности.
- «Максимальная простота» — предпочтение отдается минимальному количеству компонентов.
- «Масштабируемость превыше всего» — даже в ущерб удобству разработки.
Метод описания — это инструмент фиксации архитектуры:
- C4-модель — контекст, контейнеры, компоненты, код.
- UML — универсальный язык моделирования.
- ADR (Architectural Decision Records) — текстовые записи ключевых решений.
- Простые схемы + пояснения — для небольших проектов.
Выбор метода зависит от сложности системы и культуры команды. Главное — чтобы описание было понятно, актуально и поддерживалось.