Лекция 39 мин.
Архитектура программного обеспечения — это основа, на которой строится любое цифровое решение. Она определяет не отдельные строки кода и не конкретные технологии, а общий способ организации системы: как ее части связаны между собой, как распределяются обязанности, как обеспечивается развитие, устойчивость и понятность проекта.
Без архитектуры программный продукт может работать на начальном этапе, но со временем становится все сложнее в поддержке. Изменения начинают требовать больше времени, ошибки появляются чаще, а развитие системы становится непредсказуемым. Именно поэтому архитектура нужна не только крупным проектам, но и любому программному решению, которое должно развиваться, масштабироваться и оставаться управляемым.
Следует различать архитектурные стили и паттерны.
Архитектурный стиль — это более широкая категория, задающая общие принципы построения систем (например, клиент-сервер, микросервисы, слойная архитектура).
Архитектурный паттерн — конкретное решение для организации структуры и взаимодействия компонентов внутри системы.
Сущность архитектуры заключается в создании понятной структуры системы. Она помогает определить, из каких частей состоит программа, какую роль выполняет каждая часть и каким образом они взаимодействуют между собой.
Архитектура отвечает не столько на вопрос «как написать код», сколько на вопрос «как организовать систему так, чтобы она могла жить и развиваться». Это своего рода каркас, который удерживает проект от хаоса и помогает принимать технические решения осознанно.
Хорошая архитектура делает систему более понятной для разработчиков, более устойчивой к изменениям и более удобной для сопровождения. Она снижает зависимость отдельных частей друг от друга и позволяет развивать продукт без полного переписывания.
Архитектура нужна для того, чтобы программная система была не просто работоспособной, а управляемой, надежной и готовой к изменениям. Она помогает заранее продумать ключевые решения, которые будут влиять на весь жизненный цикл продукта.
Основные задачи архитектуры:
| Задача | Значение |
|---|---|
| Организация системы | Помогает разделить проект на понятные части |
| Управление сложностью | Позволяет не допустить хаотичного роста кода |
| Поддержка развития | Упрощает добавление новых возможностей |
| Повышение надежности | Снижает риск ошибок при изменениях |
| Улучшение сопровождения | Делает систему понятнее для команды |
| Согласование решений | Помогает всем участникам проекта мыслить в одной логике |
Архитектура особенно важна, когда проект развивается долго, над ним работает команда, требования меняются, а продукт должен оставаться стабильным и удобным для доработки.
Архитектура программного обеспечения строится на ряде общих принципов. Они помогают создавать системы, которые проще понимать, изменять и поддерживать.
| Принцип | Суть |
|---|---|
| Разделение ответственности | Каждая часть системы должна выполнять свою понятную задачу |
| Слабая связанность | Компоненты не должны чрезмерно зависеть друг от друга |
| Высокая связность внутри модуля | Все, что относится к одной задаче, должно находиться рядом логически |
| Простота | Архитектура должна решать задачу без лишнего усложнения |
| Гибкость | Система должна допускать изменения без разрушения всей структуры |
| Масштабируемость мышления | Архитектура должна позволять проекту расти без потери управляемости |
| Понятность | Решения должны быть ясны не только автору, но и другим участникам команды |
| Устойчивость к изменениям | Изменение одной части не должно непредсказуемо ломать всю систему |
Главная идея этих принципов — сделать систему не случайным набором кода, а продуманной конструкцией, где каждое решение имеет свое место и назначение.
Хорошая архитектура должна учитывать не только текущие задачи, но и возможное развитие продукта. Она не обязана быть сложной, но должна быть достаточно продуманной, чтобы выдерживать изменения.
К ключевым требованиям относятся:
| Требование | Описание |
|---|---|
| Понятность | Структура системы должна быть легко объяснима |
| Поддерживаемость | Код должно быть удобно изменять и сопровождать |
| Расширяемость | Новые функции должны добавляться без разрушения существующей логики |
| Надежность | Система должна сохранять стабильность при изменениях и нагрузках |
| Гибкость | Архитектура должна адаптироваться к новым требованиям |
| Контролируемость сложности | Проект не должен превращаться в набор случайных зависимостей |
| Единообразие решений | Внутри системы должны использоваться согласованные подходы |
| Тестируемость | Систему должно быть удобно проверять на корректность |
Важно понимать, что хорошая архитектура — это не самая сложная архитектура. Напротив, сильная архитектура часто отличается ясностью, умеренностью и соответствием реальным задачам проекта.
Архитектура важна не только для самой системы, но и для людей, которые с ней работают. Она создает общий язык между разработчиками, аналитиками, руководителями и другими участниками проекта.
Когда архитектура понятна, команда быстрее принимает решения, легче находит нужные части системы и меньше спорит о базовой организации проекта. Это особенно важно при росте команды, передаче проекта новым разработчикам или длительном сопровождении продукта.
Архитектура помогает избежать ситуации, когда каждый разработчик реализует решения по-своему. Она задает общие правила и делает развитие продукта более предсказуемым.
Программная система почти всегда меняется: появляются новые требования, изменяются бизнес-процессы, растет количество пользователей, добавляются новые функции. Архитектура позволяет системе адаптироваться к этим изменениям.
Без архитектурного подхода каждое изменение может становиться все дороже и рискованнее. С продуманной архитектурой развитие остается более контролируемым: команда понимает, куда добавлять новую логику, какие части затронет изменение и как не нарушить уже работающие механизмы.
Таким образом, архитектура — это не разовое решение в начале проекта, а постоянный инструмент управления качеством и развитием программного продукта.
| Уровень | Что описывает | Примеры |
|---|---|---|
| UI-уровень | Как устроен интерфейс и его логика | MVC, MVP, MVVM |
| Архитектура приложения | Как организован код внутри приложения | Layered, Clean, Hexagonal, Onion, Modular Monolith |
| Доменный уровень | Как моделируется бизнес-логика | DDD, Aggregates, Bounded Contexts |
| Системный уровень | Как приложение разделено на крупные части | Monolith, Client-Server, SOA, Microservices |
| Интеграционный уровень | Как части системы общаются | REST, GraphQL, Message Queue, Event-Driven |
| Deployment / Infrastructure уровень | Как система развертывается и масштабируется | Serverless, Cloud-Native, Kubernetes-based архитектура |

Ниже — обзор популярных видов программной архитектуры. Годы указаны примерно, потому что многие подходы появлялись постепенно: сначала как практика, потом как термин.
| Архитектура | Примерные годы появления / популяризации | Уровень |
Главная особенность достоинства и недостатки |
|---|---|---|---|
| Монолитная архитектура | 1960–1970-е | Архитектура приложения |
Все приложение собрано и развертывается как единое целое +Простая разработка на старте; легко запускать; проще отлаживать; меньше инфраструктуры -Сложно масштабировать частями; со временем код может стать запутанным; любое изменение требует деплоя всего приложения |
| Модульный монолит | 1990-е / 2000-е | Архитектура приложения |
Один deployable artifact, но внутри четкое разделение на модули +Хороший баланс простоты и структуры; легче поддерживать; проще, чем микросервисы -Требует дисциплины; границы модулей легко нарушить; масштабирование все еще в рамках одного приложения |
| Клиент-серверная архитектура | 1980-е | Системная архитектура |
Клиент запрашивает данные или функции у сервера +Разделение UI и серверной логики; централизованные данные; удобно для сетевых приложений -Сервер может стать узким местом; зависимость от сети; сложность синхронизации |
| Трехуровневая архитектура | 1990-е | Архитектура приложения / системы |
Разделение на presentation, business logic, data layer +Понятная структура; слои можно развивать отдельно; хорошо подходит для корпоративных систем -Может стать слишком формальной; бизнес-логика иногда размазывается между слоями |
| N-tier архитектура | 1990-е | Системная архитектура |
Несколько логических или физических уровней: UI, API, бизнес-логика, БД и т.д. +Гибкость; можно разделять нагрузку; удобно для enterprise-систем -Больше сложности; больше сетевых вызовов; выше задержки |
| Layered Architecture / Слоистая архитектура | 1970-е / 1980-е | Архитектура приложения |
Код делится на слои: controller, service, repository, database +Простая и понятная; хорошо подходит большинству CRUD-приложений; легко обучать команду -Может приводить к анемичной модели; часто появляется много «прокладочных» классов; не всегда хорошо выражает бизнес-домен |
| MVC | 1979 / 1980-е | Архитектура UI / приложения |
Разделение на Model, View, Controller +Удобно разделять интерфейс и логику; широко известно; много фреймворков -В больших проектах controller может разрастаться; разные фреймворки трактуют MVC по-разному |
| MVP | 1990-е | Архитектура UI |
View максимально пассивна, Presenter управляет логикой отображения +Удобно тестировать UI-логику; хорошее разделение ответственности -Много шаблонного кода; Presenter может стать слишком большим |
| SOA, Service-Oriented Architecture | 1990-е / 2000-е | Корпоративная / системная архитектура |
Система состоит из сервисов, часто с централизованной интеграцией +Повторное использование сервисов; интеграция больших enterprise-систем; стандартизация -Может быть тяжеловесной; сложная инфраструктура; часто появляется централизованная шина как bottleneck |
| Сервисная шина предприятия ( enterprise service bus, ESB) | 2000-е | интеграционная архитектура |
рассматривается как реализация Service-Oriented Architecture (SOA). Основной принцип сервисной шины — концентрация обмена сообщениями между различными системами через единую точку, в которой, при необходимости, обеспечивается транзакционный контроль, преобразование данных, сохранность сообщений. Все настройки обработки и передачи сообщений предполагаются также сконцентрированными в единой точке, и формируются в терминах служб, таким образом, при замене какой-либо информационной системы, подключенной к шине, нет необходимости в перенастройке остальных систем. Наименование подобрано по аналогии с системной шиной компьютера, позволяющей подключать несколько устройств и передавать данные между ними по одному набору проводников. Основные преимущества
Основные недостатки
|
| Микросервисная архитектура | 2010-е | Системная / deployment-архитектура |
Система состоит из маленьких независимо развертываемых сервисов +Независимый deploy; масштабирование отдельных частей; автономные команды; разные технологии для разных сервисов -Высокая сложность инфраструктуры; distributed transactions; мониторинг, сеть, DevOps, observability становятся обязательными |
| Event-Driven Architecture | 2000-е / 2010-е | Системная архитектура |
Компоненты общаются через события +Слабая связанность; хорошая масштабируемость; удобно для асинхронных процессов -Сложнее отлаживать; eventual consistency; труднее проследить поток выполнения |
| Event Sourcing* | 2000-е / 2010-е | Архитектурный паттерн хранения состояния |
Состояние хранится как последовательность событий +Полная история изменений; можно восстановить состояние на любой момент; удобно для аудита -Сложность миграций событий; сложнее запросы; требует хорошей модели событий |
| DDD Architecture* | 2003 | Архитектура доменной модели / подход к проектированию |
Архитектура строится вокруг бизнес-домена, bounded contexts и aggregates +Хорошо подходит для сложной бизнес-логики; помогает определить границы модулей и сервисов; общий язык с бизнесом -Сложна в освоении; не нужна для простого CRUD; требует участия доменных экспертов |
| MVVM | 2005 примерно | Архитектура UI |
View связана с ViewModel через binding +Хорошо подходит для реактивных UI; меньше ручного кода для обновления интерфейса; удобно тестировать ViewModel -Сложность binding-механизмов; иногда трудно отлаживать; ViewModel может разрастаться |
| Hexagonal Architecture / Ports and Adapters | 2005 | Архитектура приложения |
Домен изолирован от внешнего мира через порты и адаптеры +Хорошая тестируемость; независимость от БД, UI, фреймворков; чистая бизнес-логика -Больше абстракций; может быть избыточной для простых CRUD-систем |
| ECS (Entity-Component-System |
примерно 2007 1998 — Thief: The Dark Project: первые идеи композиции игровых объектов через компоненты. 2002 — Dungeon Siege (Scott Bilas): формализация подхода «Data-Driven Game Object System». 2007 — Operation Flashpoint: Dragon Rising: команда разработчиков экспериментировала с ECS. |
архитектурный паттерн |
позволяет разделять данные и логику, обеспечивая гибкость, масштабируемость и высокую производительность. Основные элементы ECS Component — данные, описывающие свойства сущности (позиция, здоровье, скорость). Компоненты не содержат логики. System — набор функций, которые обрабатывают данные компонентов (например, система движения обновляет позицию на основе скорости). |
| Clean Architecture | 2012 примерно | Архитектура приложения |
Зависимости направлены внутрь: к domain/use cases +Независимость от фреймворков; высокая тестируемость; хорошо защищает бизнес-логику -Много слоев и интерфейсов; требует опыта; может быть чрезмерной для маленьких проектов |
| Onion Architecture | 2008 примерно | Архитектура приложения |
Домен в центре, инфраструктура снаружи +Похожа на Clean/Hexagonal; хорошо отделяет бизнес-логику от деталей хранения и доставки -Может быть сложно правильно применять; требует дисциплины в зависимостях |
| CQRS | 2010-е | Архитектурный паттерн |
Разделение команд изменения данных и запросов чтения +Оптимизация чтения и записи отдельно; удобно для сложных доменов; хорошо сочетается с event sourcing -Усложняет систему; дублирование моделей; eventual consistency |
| Serverless Architecture | 2014–2015 | Cloud / deployment-архитектура |
Код запускается как функции или managed-сервисы без управления серверами +Не нужно управлять серверами; auto-scaling; оплата за использование -Vendor lock-in; cold start; сложнее локальная отладка; ограничения платформы |
| Microkernel / Plugin Architecture | 1980-е / 1990-е | Архитектура приложения |
Есть ядро системы и подключаемые плагины +Гибкое расширение; удобно для IDE, CMS, браузеров, платформ -Сложность API плагинов; риск несовместимости; ядро должно быть очень хорошо спроектировано |
| Pipe and Filter | 1970-е | Архитектура обработки данных |
Данные проходят через цепочку независимых фильтров +Простота композиции; хороша для ETL, компиляторов, обработки потоков -Не всегда подходит для интерактивных систем; может быть сложно управлять состоянием |
| Peer-to-Peer, P2P | 1990-е / 2000-е | Распределенная архитектура |
Узлы взаимодействуют напрямую без центрального сервера +Нет единой точки отказа; хорошая распределенность; масштабируется количеством участников -Сложность безопасности; сложнее контроль данных; нестабильность узлов |
| REST Architecture | 2000 | API-архитектура |
Ресурсы доступны через HTTP-методы и URI +Простота; хорошо подходит для веб-API; кэширование; широкая поддержка -Не всегда удобен для сложных операций; может приводить к overfetching/underfetching |
| GraphQL Architecture | 2015 | API-архитектура |
Клиент сам указывает, какие данные ему нужны +Меньше лишних данных; удобно для сложных frontend-приложений; один endpoint -Сложность кэширования; риск тяжелых запросов; нужна защита от перегрузки |
| Broker / Message Queue Architecture | 1990-е / 2000-е | Интеграционная архитектура |
Компоненты общаются через брокер сообщений +Асинхронность; устойчивость к временным сбоям; слабая связанность -Сложность мониторинга; задержки; возможны дубликаты сообщений |
| Cloud-Native Architecture | 2010-е | Cloud / системная архитектура |
Приложения проектируются под контейнеры, автоматическое масштабирование, отказоустойчивость +Высокая масштабируемость; удобный deploy; resilience; хорошо подходит для Kubernetes -Высокий порог входа; сложная инфраструктура; требует зрелого DevOps |
Не все эти архитектуры являются альтернативами друг другу. Их часто комбинируют.
Например, реальная система может быть такой:
Microservices ├── Order Service: Clean Architecture + DDD + REST ├── Payment Service: Hexagonal Architecture + Events ├── Notification Service: Event-Driven └── Frontend: MVVM или MVC
То есть микросервисы отвечают за разделение системы, DDD — за бизнес-модель, Clean/Hexagonal — за структуру кода внутри сервиса, а REST/Event-driven — за взаимодействие между частями.
Монолитная архитектура программного обеспечения — это подход, при котором все основные компоненты приложения объединены в единый программный блок.
В монолите пользовательский интерфейс, бизнес-логика, работа с базой данных и другие модули обычно разрабатываются, развертываются и масштабируются вместе. Такое приложение проще создать и запустить на ранних этапах, но по мере роста системы его становится сложнее изменять, тестировать, масштабировать и поддерживать.

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

Клиент-серверная архитектура — это подход, при котором система разделяется на две основные части: клиент и сервер.
Клиент отвечает за взаимодействие с пользователем: отображает интерфейс, принимает действия пользователя и отправляет запросы. Сервер обрабатывает эти запросы, выполняет бизнес-логику, работает с базой данных и возвращает результат клиенту.
Такой подход позволяет централизованно хранить данные и логику на сервере, а клиентские приложения могут быть разными: веб-сайт, мобильное приложение, desktop-приложение или другое устройство.

Трехуровневая архитектура — это подход к построению приложения, при котором система разделяется на три логических уровня:
1. Уровень представления — отвечает за пользовательский интерфейс: веб-страницы, мобильное приложение или desktop-клиент.
2. Уровень бизнес-логики — обрабатывает запросы пользователя, выполняет правила приложения, проверки, расчеты и основную логику системы.
3. Уровень данных — отвечает за хранение и получение данных, обычно через базу данных или файловое хранилище.
Главная идея такой архитектуры — разделить интерфейс, логику и данные, чтобы систему было проще разрабатывать, поддерживать, тестировать и масштабировать.

N-tier архитектура — это архитектурный подход, при котором приложение разделяется на несколько независимых логических уровней — tiers.
Обычно система включает уровень представления, уровень бизнес-логики, уровень доступа к данным, уровень хранения данных и дополнительные уровни, например API-шлюз, кэш, интеграции или сервисы безопасности.
Главная идея N-tier архитектуры — разделить ответственность между слоями. Каждый уровень выполняет свою задачу и взаимодействует с соседними уровнями через определенные интерфейсы. Это делает систему более гибкой, масштабируемой и удобной для сопровождения по сравнению с простым монолитом или классической трехуровневой архитектурой.

Layered Architecture / Слоистая архитектура — это архитектурный подход, при котором приложение разделяется на несколько слоев, и каждый слой отвечает за свою часть системы.
Обычно выделяют слой представления, слой приложения, слой бизнес-логики, слой доступа к данным и слой хранения данных. Верхние слои используют нижние, но не должны напрямую вмешиваться в их внутреннюю реализацию.
Главная идея слоистой архитектуры — разделение ответственности. Это помогает упорядочить код, упростить поддержку, тестирование и развитие системы, так как изменения в одном слое меньше затрагивают остальные части приложени

MVC архитектура — это архитектурный подход, при котором приложение разделяется на три основные части: Model, View и Controller.
Model / Модель отвечает за данные, бизнес-логику и правила работы с ними. View / Представление отвечает за отображение информации пользователю. Controller / Контроллер принимает действия пользователя, обрабатывает запросы и связывает модель с представлением.
Главная идея MVC — разделить логику приложения, данные и пользовательский интерфейс. Это упрощает разработку, тестирование и поддержку системы, потому что изменения в интерфейсе меньше затрагивают бизнес-логику и наоборот.

MVP архитектура — это архитектурный подход, в котором приложение разделяется на три части: Model, View и Presenter.
Model / Модель отвечает за данные, бизнес-логику и работу с источниками данных. View / Представление отвечает только за отображение интерфейса и передачу действий пользователя. Presenter / Презентер получает события от View, обращается к Model, обрабатывает результат и обновляет View.
Главная идея MVP — отделить пользовательский интерфейс от логики управления. Это упрощает тестирование, поддержку и изменение интерфейса, потому что основная логика взаимодействия находится в Presenter, а View остается максимально «пассивным».

MVVM архитектура — это архитектурный подход, при котором приложение разделяется на три основные части: Model, View и ViewModel.
Model / Модель отвечает за данные, бизнес-логику и работу с источниками данных. View / Представление отвечает за пользовательский интерфейс и отображение данных. ViewModel / Модель представления связывает View и Model: подготавливает данные для отображения, обрабатывает команды пользователя и управляет состоянием интерфейса.
Главная идея MVVM — отделить интерфейс от логики отображения и состояния. Это удобно для приложений с активным пользовательским интерфейсом, так как View может автоматически обновляться при изменении данных через привязку данных (data binding).

SOA / Service-Oriented Architecture / Сервис-ориентированная архитектура — это подход, при котором приложение строится как набор отдельных сервисов, взаимодействующих друг с другом через стандартизированные интерфейсы.
Каждый сервис отвечает за определенную бизнес-функцию, например управление пользователями, заказами, оплатами или уведомлениями. Сервисы могут быть разработаны на разных технологиях и переиспользоваться в разных системах.
Главная идея SOA — разделить крупную систему на автономные сервисы с четкими контрактами взаимодействия. Это повышает гибкость, повторное использование компонентов и упрощает интеграцию между разными приложениями и корпоративными системами.

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

Event-Driven Architecture / Событийно-ориентированная архитектура — это подход, при котором компоненты системы взаимодействуют через события.
Событие означает, что в системе что-то произошло: пользователь зарегистрировался, заказ создан, платеж выполнен, товар добавлен на склад. Один компонент публикует событие, а другие компоненты подписываются на него и реагируют независимо.
Главная идея Event-Driven Architecture — уменьшить жесткую связь между частями системы. Компоненты не обязаны напрямую вызывать друг друга: они обмениваются событиями через брокер сообщений или шину событий. Это повышает гибкость, масштабируемость и удобство асинхронной обработки, но требует хорошего контроля доставки, порядка событий и обработки ошибок.

Event Sourcing Архитектурный паттерн хранения состояния
Event Sourcing — это архитектурный паттерн, при котором состояние системы хранится не как текущая запись, а как последовательность событий, которые привели систему к этому состоянию.
Например, вместо хранения только статуса заказа «оплачен», система сохраняет цепочку событий: заказ создан → товар добавлен → оплата выполнена → заказ подтвержден. Текущее состояние можно восстановить, последовательно применив все события.
Главная идея Event Sourcing — фиксировать историю изменений как основной источник истины. Это дает полный аудит действий, возможность восстановить состояние на любой момент времени и проще анализировать бизнес-процессы, но требует аккуратной работы с версиями событий, порядком обработки и хранением больших объемов истории

DDD Architecture / Domain-Driven Design — это подход к проектированию программного обеспечения, при котором структура системы строится вокруг предметной области и бизнес-логики, а не вокруг базы данных или фреймворка.
Главная идея DDD — сделать код максимально близким к реальным бизнес-понятиям: заказ, клиент, платеж, товар, склад, бронь и т.д. Бизнес-правила размещаются в доменном слое, а технические детали — база данных, API, UI, очереди сообщений — выносятся наружу.
DDD помогает строить систему вокруг бизнес-модели, где главные правила находятся в доменном слое, а технические детали подключаются отдельно и не управляют архитектурой приложения.
Объект с уникальным идентификатором.
Пример:
User
Order
Product
Payment
Например, два заказа могут иметь одинаковую сумму, но это разные сущности, потому что у них разные OrderId.
public class Order
{
public OrderId Id { get; private set; }
public OrderStatus Status { get; private set; }
public List<OrderItem> Items { get; private set; }
public void Confirm()
{
if (!Items.Any())
throw new Exception("Нельзя подтвердить пустой заказ");
Status = OrderStatus.Confirmed;
}
}
Объект без собственного идентификатора. Его важность определяется значением полей.
Пример:
Money
Email
Address
FullName
DateRange
public class Money
{
public decimal Amount { get; }
public string Currency { get; }
public Money(decimal amount, string currency)
{
Amount = amount;
Currency = currency;
}
}
Группа связанных объектов, которые изменяются как единое целое.
Пример:
Order
├── OrderItem
├── DeliveryAddress
└── PaymentInfo
Обычно у агрегата есть главный объект — Aggregate Root.
Order = Aggregate Root
OrderItem = внутренняя часть агрегата
Внешний код должен работать только через Order, а не напрямую менять OrderItem.
Класс или интерфейс для сохранения и получения агрегатов.
public interface IOrderRepository
{
Task<Order?> GetByIdAsync(OrderId id);
Task SaveAsync(Order order);
}
Репозиторий скрывает детали базы данных от доменной логики.
Класс для бизнес-логики, которая не принадлежит одной конкретной сущности.
Пример:
PricingService
PaymentPolicy
DeliveryCostCalculator
public class DeliveryCostCalculator
{
public Money Calculate(Address address, List<OrderItem> items)
{
// бизнес-правила расчета доставки
}
}
Координирует выполнение сценариев использования: создать заказ, оплатить заказ, отменить заказ.
public class CreateOrderUseCase
{
private readonly IOrderRepository _orders;
public async Task Execute(CreateOrderCommand command)
{
var order = Order.Create(command.UserId, command.Items);
await _orders.SaveAsync(order);
}
}
Он не должен содержать сложную бизнес-логику. Он вызывает доменные объекты и репозитории.
Факт, который уже произошел в предметной области.
OrderCreated
OrderPaid
UserRegistered
ProductReserved
public class OrderPaidEvent
{
public OrderId OrderId { get; }
public DateTime PaidAt { get; }
}
Пример для проекта интернет-магазина:
src/
└── Shop/
├── Domain/
│ ├── Orders/
│ │ ├── Order.cs
│ │ ├── OrderId.cs
│ │ ├── OrderItem.cs
│ │ ├── OrderStatus.cs
│ │ ├── IOrderRepository.cs
│ │ ├── OrderCreatedEvent.cs
│ │ └── Services/
│ │ └── OrderPricingService.cs
│ │
│ ├── Users/
│ │ ├── User.cs
│ │ ├── UserId.cs
│ │ └── Email.cs
│ │
│ ├── Products/
│ │ ├── Product.cs
│ │ ├── ProductId.cs
│ │ └── Money.cs
│ │
│ └── Shared/
│ ├── Entity.cs
│ ├── ValueObject.cs
│ └── DomainEvent.cs
│
├── Application/
│ ├── Orders/
│ │ ├── CreateOrder/
│ │ │ ├── CreateOrderCommand.cs
│ │ │ └── CreateOrderHandler.cs
│ │ ├── PayOrder/
│ │ │ ├── PayOrderCommand.cs
│ │ │ └── PayOrderHandler.cs
│ │ └── CancelOrder/
│ │ ├── CancelOrderCommand.cs
│ │ └── CancelOrderHandler.cs
│ │
│ └── Users/
│ └── RegisterUser/
│ ├── RegisterUserCommand.cs
│ └── RegisterUserHandler.cs
│
├── Infrastructure/
│ ├── Persistence/
│ │ ├── AppDbContext.cs
│ │ ├── OrderRepository.cs
│ │ └── UserRepository.cs
│ │
│ ├── Messaging/
│ │ └── EventPublisher.cs
│ │
│ └── ExternalServices/
│ ├── PaymentGateway.cs
│ └── EmailSender.cs
│
└── Presentation/
├── Controllers/
│ ├── OrdersController.cs
│ └── UsersController.cs
│
└── DTOs/
├── CreateOrderRequest.cs
└── RegisterUserRequest.cs
Presentation
Принимает HTTP-запросы, показывает UI, вызывает Application.
Application
Описывает сценарии использования: создать заказ, оплатить заказ, зарегистрировать пользователя.
Domain
Содержит главную бизнес-логику: сущности, агрегаты, правила, события, value objects.
Infrastructure
Работает с базой данных, внешними API, очередями сообщений, файловыми системами и другими техническими деталями.

Hexagonal Architecture / Ports and Adapters / Гексагональная архитектура — это архитектурный подход, при котором бизнес-логика приложения находится в центре системы и не зависит от внешних технологий.
В центре располагается ядро приложения: доменная модель, бизнес-правила и сценарии использования. Внешние элементы — база данных, веб-интерфейс, API, очереди сообщений, файловые системы или сторонние сервисы — подключаются к ядру через порты и адаптеры.
Порты описывают интерфейсы взаимодействия, а адаптеры реализуют подключение к конкретным технологиям. Главная идея такой архитектуры — изолировать бизнес-логику от инфраструктуры, чтобы систему было проще тестировать, изменять и переносить на другие технологии.

ECS / Entity-Component-System — это архитектурный подход, часто используемый в игровых движках и симуляциях, где объекты системы разделяются на сущности, компоненты и системы.
Entity / Сущность — это объект или идентификатор, например игрок, враг, предмет или транспорт. Component / Компонент хранит данные сущности, например позицию, здоровье, скорость или внешний вид. System / Система содержит логику обработки компонентов, например движение, физику, рендеринг или столкновения.
Главная идея ECS — отделить данные от поведения. Сущности состоят из набора компонентов, а системы обрабатывают все сущности с нужными компонентами. Это делает архитектуру гибкой, производительной и удобной для массовой обработки большого количества объектов.
Почему ECS удобен в играх
Производительность: данные хранятся компактно и эффективно используют кэш процессора. Это особенно важно для игр с большим количеством объектов.
Гибкость: легко добавлять новые компоненты и системы без переписывания кода.
Масштабируемость: подходит для сложных игровых миров с тысячами сущностей.
Повторное использование: системы можно применять к разным сущностям, что снижает дублирование кода.
Сравнение ECS и ООП
| Подход | Хранение данных | Логика | Производительность | Применимость |
|---|---|---|---|---|
| ООП | Внутри объектов | Методы внутри классов | Снижается при большом числе объектов | Подходит для небольших проектов |
| ECS | В отдельных структурах (компонентах) | В системах | Высокая за счет Data-Oriented Design | Идеален для масштабных игр |
В Unity ситуация такая:
Базовый уровень (GameObject + Component) — изначально Unity использует компонентную модель: любой объект в сцене — это GameObject, к которому можно прикреплять разные MonoBehaviour-компоненты. Это не чистый ECS, но близкий по духу подход. То есть базовый Unity уже «компонентный», но не «системный» в строгом ECS-смысле.
Чистый ECS (Unity DOTS) — полноценная реализация ECS появилась как отдельный пакет: DOTS (Data-Oriented Technology Stack). Он включает:
Entities — ядро ECS, где сущности — это ID, а данные хранятся в компонентах-структурах.
Jobs System — многопоточная обработка систем.
Burst Compiler — компилятор для максимальной оптимизации кода.
Вывод:
Встроенный Unity (GameObject + MonoBehaviour) — это компонентная архитектура, но не полноценный ECS.
Для настоящего ECS нужен отдельный пакет DOTS (Entities + Jobs + Burst).
| Подход | Встроенный Unity | Unity DOTS (ECS) |
|---|---|---|
| Модель | GameObject + MonoBehaviour | Entity + Component + System |
| Производительность | Средняя, зависит от количества объектов | Высокая, оптимизация под кэш и многопоточность |
| Гибкость | Удобно для небольших проектов | Идеально для больших миров и тысяч объектов |
| Нужен пакет? | Нет, встроено | Да, нужен Entities/Jobs/Burst |

Clean Architecture / Чистая архитектура — это архитектурный подход, при котором бизнес-логика приложения находится в центре системы и не зависит от внешних деталей.
Внутри располагаются сущности, бизнес-правила и сценарии использования. Внешние слои отвечают за интерфейс, контроллеры, базы данных, API, фреймворки и другие технические детали.
Главная идея Clean Architecture — зависимости должны быть направлены внутрь, к бизнес-логике. Это позволяет менять базу данных, UI, фреймворк или внешние сервисы без серьезного влияния на ядро приложения, а также упрощает тестирование и поддержку системы.

Onion Architecture / Луковая архитектура — это архитектурный подход, при котором приложение строится в виде нескольких концентрических слоев вокруг доменной модели.
В центре находится Domain / Домен: сущности, value objects, бизнес-правила и доменные сервисы. Внешние слои содержат Application / Use Cases, интерфейсы, инфраструктуру, базу данных, API, UI и внешние сервисы.
Главная идея Onion Architecture — зависимости направлены только внутрь, к доменной логике. Домен не должен зависеть от базы данных, фреймворков или интерфейса. Благодаря этому бизнес-логику проще тестировать, поддерживать и переносить на другие технологии.

CQRS / Command Query Responsibility Segregation — это архитектурный подход, при котором операции изменения данных и операции чтения данных разделяются.
В CQRS обычно выделяют две стороны:
Command Side / Сторона команд — отвечает за действия, которые изменяют состояние системы: создать заказ, оплатить заказ, отменить бронь, изменить профиль пользователя.
Query Side / Сторона запросов — отвечает только за чтение данных: получить список заказов, показать карточку пользователя, вывести отчет или статистику.
Главная идея CQRS — не смешивать логику записи и чтения. Это позволяет отдельно оптимизировать запись и чтение, использовать разные модели данных, повысить производительность и упростить сложную бизнес-логику. Часто CQRS применяется вместе с Event Sourcing и Event-Driven Architecture.

Serverless Architecture / Бессерверная архитектура — это архитектурный подход, при котором разработчик не управляет серверами напрямую, а размещает код и сервисы в облачной платформе.
Приложение обычно состоит из отдельных функций, API-шлюзов, управляемых баз данных, очередей сообщений, файловых хранилищ и других облачных сервисов. Код запускается по событию: HTTP-запрос, загрузка файла, сообщение в очереди, изменение данных или расписание.
Главная идея Serverless — сосредоточиться на бизнес-логике, а инфраструктуру, масштабирование, отказоустойчивость и запуск серверов передать облачному провайдеру. Это удобно для событийных и переменных нагрузок, но требует учитывать ограничения платформы, холодные старты, стоимость вызовов и зависимость от облачного поставщика.

Microkernel / Plugin Architecture / Микроядерная архитектура — это архитектурный подход, при котором приложение состоит из небольшого базового ядра и набора подключаемых модулей — плагинов.
Ядро системы содержит минимальную основную функциональность: запуск приложения, общие правила, управление жизненным циклом, регистрацию и вызов плагинов. Плагины добавляют конкретные возможности: импорт данных, отчеты, интеграции, дополнительные форматы, бизнес-расширения или пользовательские функции.
Главная идея Microkernel Architecture — сделать систему расширяемой без изменения основного ядра. Новые функции можно добавлять, удалять или обновлять как отдельные плагины, что удобно для платформ, IDE, CMS, браузеров, корпоративных систем и продуктов с большим количеством расширений.

Pipe and Filter Architecture / Архитектура “Каналы и фильтры” — это архитектурный подход, при котором обработка данных разбивается на последовательность независимых этапов.
Filter / Фильтр — это отдельный обработчик, который получает входные данные, выполняет над ними одну конкретную операцию и передает результат дальше.
Pipe / Канал — это механизм передачи данных между фильтрами.
Главная идея Pipe and Filter — построить систему как цепочку обработки: входные данные → фильтр 1 → фильтр 2 → фильтр 3 → результат. Такой подход удобен для обработки потоков данных, ETL-процессов, компиляции, логирования, обработки изображений, аудио, видео и очередей сообщений. Он упрощает добавление, замену и повторное использование отдельных этапов обработки.
Работу Middleware, напрмиер, в Laravel можно рассматривать как пример Pipe and Filter Architecture, но не как всю архитектуру Laravel целиком.
В Laravel HTTP-запрос проходит через цепочку middleware:
HTTP Request
↓
Middleware 1: проверка авторизации
↓
Middleware 2: проверка CSRF
↓
Middleware 3: логирование
↓
Middleware 4: локализация
↓
Controller
↓
HTTP Response
Каждый middleware похож на Filter:
Filter = Middleware
Он получает запрос, выполняет одну задачу и передает запрос дальше.
А передача запроса между middleware похожа на Pipe:
Pipe = цепочка передачи Request → next()
Но важно: Laravel в целом не является только Pipe and Filter архитектурой. Laravel чаще сочетает несколько подходов:
MVC — Controllers, Models, Views
Layered Architecture — Route → Controller → Service → Repository → DB
REST - поддержка ресурсных роутов, контроллеров
Pipe and Filter — Middleware pipeline
Event-Driven — Events / Listeners / Queues

Peer-to-Peer Architecture / P2P / Одноранговая архитектура — это архитектурный подход, при котором участники системы взаимодействуют друг с другом напрямую, без обязательного центрального сервера.
Каждый узел сети, или peer, может одновременно быть и клиентом, и сервером: он может запрашивать данные у других узлов и сам предоставлять данные или ресурсы другим участникам.
Главная идея P2P — распределить хранение, обработку и обмен данными между множеством равноправных узлов. Это повышает отказоустойчивость и масштабируемость системы, но усложняет поиск узлов, синхронизацию данных, безопасность, контроль доступа и управление сетью.

REST Architecture / Representational State Transfer — это архитектурный стиль для построения сетевых API, чаще всего веб-сервисов поверх HTTP.
В REST система работает с ресурсами: пользователи, заказы, товары, платежи. Каждый ресурс имеет свой URL, а операции над ним выполняются стандартными HTTP-методами: GET для чтения, POST для создания, PUT/PATCH для изменения, DELETE для удаления.
Главная идея REST — сделать взаимодействие клиента и сервера простым, единообразным и независимым от внутренней реализации. Клиент отправляет запрос к ресурсу, сервер обрабатывает его и возвращает представление данных, обычно в формате JSON. REST хорошо подходит для веб-приложений, мобильных приложений и интеграций между системами.

GraphQL Architecture — это архитектурный подход к построению API, при котором клиент сам указывает, какие данные ему нужны, а сервер возвращает ровно запрошенную структуру.
Вместо множества REST-эндпоинтов вроде /users, /orders, /products обычно используется один GraphQL endpoint, например /graphql. Клиент отправляет запрос с описанием нужных полей, а сервер обрабатывает его через schema, queries, mutations и resolvers.
Главная идея GraphQL — дать клиенту гибкий способ получать связанные данные без лишних или недостающих полей. Это удобно для web и mobile приложений, где разные экраны требуют разные наборы данных, но требует контроля сложности запросов, авторизации, кеширования и производительности resolver-ов.

Broker / Message Queue Architecture / Архитектура брокера сообщений — это архитектурный подход, при котором компоненты системы обмениваются данными не напрямую, а через промежуточный сервис — брокер сообщений.
Один сервис отправляет сообщение в очередь или топик, а другой сервис получает его и обрабатывает. Например, сервис заказов публикует сообщение OrderCreated, а сервис уведомлений, склад и аналитика получают его через брокер.
Главная идея этой архитектуры — уменьшить прямую зависимость между сервисами и сделать обмен данными асинхронным. Это повышает масштабируемость и устойчивость системы: если получатель временно недоступен, сообщение может остаться в очереди и быть обработано позже. При этом важно контролировать повторную доставку, порядок сообщений, ошибки обработки и идемпотентность.

Cloud-Native Architecture / Облачно-ориентированная архитектура — это подход к созданию приложений, изначально рассчитанных на работу в облачной среде.
Такие системы обычно строятся из микросервисов, контейнеров, управляемых облачных сервисов, API, очередей сообщений, автоматического масштабирования, мониторинга и CI/CD-процессов.
Главная идея Cloud-Native — сделать приложение гибким, масштабируемым и устойчивым к сбоям. Компоненты могут независимо разрабатываться, развертываться и масштабироваться, а инфраструктура управляется автоматически с помощью облачных платформ, контейнерной оркестрации и DevOps-подходов.

Языки описания архитектуры (ADLS) используются для описания архитектуры программного обеспечения. Различные организации разработали несколько различных ADLS, в том числе AADL (стандарт SAE), Wright, Acme (разработаны в университете Карнеги — Меллона), xADL (разработан в UCI), Darwin (разработан в Имперском колледже в Лондоне), DAOP-ADL (разработан в Университете Малаги), а также ByADL (университет Л’Акуилы[англ.], Италия). Общими элементами для всех этих языков являются понятия компонента, коннектора и конфигурации. Также, помимо специализированных языков, для описания архитектуры часто используется унифицированный язык моделирования UML.
Архитектура программного обеспечения — это фундамент, который определяет устойчивость, понятность и способность системы к развитию. Она помогает управлять сложностью, распределять ответственность между частями системы, снижать риски изменений и создавать условия для долгосрочного сопровождения продукта.
Ее главная ценность заключается не в формальном следовании правилам, а в создании ясной и надежной структуры. Хорошая архитектура делает программный продукт более гибким, команду — более эффективной, а развитие системы — более предсказуемым.
Именно поэтому архитектура является одной из ключевых составляющих качественной разработки программного обеспечения. Она помогает не просто создать работающую систему, а построить решение, которое сможет расти, изменяться и сохранять свою ценность со временем.
Комментарии