# Паттерны — это формы, которые принимают системы

Экспресс-курс по архитектурным паттернам. 17 известных форм системы — Layered, Hexagonal, Microservices, Event-driven, CQRS, Saga и другие — у каждой английское название, схема, карточка «проблема → идея → пример → цена» и связи с другими паттернами. В конце — шпаргалка по всем паттернам на одной странице.

- **Author:** Фёдор Чищин
- **Level:** intro
- **Reading time:** ~30 минут чтения
- **Published:** 2026-06-02
- **Source:** https://fedorthinks.com/ru/learn/architecture-patterns-express

---

## 1. Что такое паттерн

Паттерн — это проверенный ответ на проблему, которая повторяется в тысячах систем. У каждого паттерна есть имя — и почти всегда это английское имя, по которому его ищут в документации и обсуждают на собеседованиях.

### Паттерн — это имя для ответа, а не правило

> В шахматах ты не изобретаешь дебют каждую партию. Ты узнаёшь: «это сицилианская защита» — и уже знаешь, куда она обычно ведёт.

**Архитектурный паттерн (architectural pattern)** = повторяющаяся проблема + проверенная форма решения + известная цена. Когда ты говоришь «сервисам нужно реагировать на то, что происходит в другом месте», это уже решённая и названная задача — паттерн **Event-driven architecture**. Знать каталог — значит перестать изобретать и начать выбирать.

### Архитектурные паттерны ≠ паттерны проектирования

> Паттерн проектирования — как расставить мебель в одной комнате. Архитектурный паттерн — планировка всего дома.

**Паттерны проектирования (design patterns)** — Factory, Observer, Strategy — живут внутри кода одного модуля. **Архитектурные паттерны** решают, какие большие «коробки» есть в системе и какие линии между ними: что разворачивается отдельно, кто с кем разговаривает, где живут данные. Этот курс — про планировки, а не про мебель.

### Карта: 17 паттернов в шести группах

> Карта метро: сначала видишь линии целиком, потом едешь по станциям.

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

_Diagram: Шесть групп паттернов — по ним идут главы 2–7._

### Как читать каждый паттерн

> Паспорт: одинаковые поля у всех, поэтому их легко сравнивать.

У каждого паттерна дальше одно и то же: **английское название** (запомни его — это термин), образ из жизни, **схема** и **карточка** с полями: _проблема_ (что болит), _идея_ (как решает), _пример_, _цена_ (что ты платишь), _когда брать_ и _связи_ с другими паттернами. Главное правило: **лучшего паттерна не бывает — бывает подходящий**, и у каждого есть счёт, который надо прочитать до того, как подписал.

> **Прежде чем тянуться за паттерном:** «Какую повторяющуюся проблему решает эта форма — и есть ли у меня эта проблема на самом деле?»

> Ты выбираешь не знаменитый паттерн. Ты выбираешь тот, чью цену можешь себе позволить.

## 2. Устройство одного приложения

Большинство систем начинаются как одно разворачиваемое приложение. Первые три паттерна — о том, как устроить его изнутри, чтобы оно не превратилось в кашу.

### Layered Architecture — слоистая архитектура

> Ресторан: зал принимает заказ, кухня готовит, кладовая хранит. Официант не готовит, повар не бегает в погреб — каждый говорит только со слоем под собой.

Самый распространённый паттерн. Код делится на горизонтальные **слои (layers)**, и запрос проходит сквозь них сверху вниз. Каждый слой знает только про слой ниже.

_Diagram: Запрос спускается по слоям: контроллер → сервис → репозиторий → база._

#### Layered Architecture (слоистая, n-tier)

- **Проблема:** Весь код в одной куче: изменения в интерфейсе ломают работу с базой.
- **Идея:** Разложить код по этажам: представление, бизнес-логика, доступ к данным, база.
- **Пример:** Веб-приложение: `Controller` зовёт `Service`, тот — `Repository`, тот — Postgres.
- **Цена:** Всё разворачивается одним куском; мелкая правка = передеплой всего.
- **Когда брать:** Почти всегда как стартовая форма для одного приложения.
- **Связи:** Основа для **Modular Monolith**; внутри слоёв часто применяют **Hexagonal**.

### Modular Monolith — модульный монолит

> Многоквартирный дом: одна крыша и один вход, но у каждой квартиры свои стены и дверь. Через спальню соседа к лестнице не ходят.

По-прежнему одно приложение, но внутри оно разрезано на **модули (modules)** по бизнес-смыслу — биллинг, каталог, аккаунты. Модули общаются только через публичный интерфейс и не лезут в чужие таблицы.

_Diagram: Одно приложение, крепкие стены внутри: модули говорят только через публичный интерфейс._

#### Modular Monolith (модульный монолит)

- **Проблема:** Монолит превращается в «большой ком грязи»: всё зависит от всего.
- **Идея:** Режем по бизнес-модулям с чёткими интерфейсами, но деплоим одним куском.
- **Пример:** Модуль `catalog` вызывает только публичные функции `billing`, а не его таблицы.
- **Цена:** Нужна дисциплина границ (их легко нарушить, если не проверять инструментом).
- **Когда брать:** **Правильный дефолт почти для всех** — ясность микросервисов без сети.
- **Связи:** Естественно **вырастает в Microservices**: модуль выносится в сервис, когда нужно.

### MVC / MVVM — держать экран подальше от мозгов

> Театр: сценарий, актёры с режиссёром и сцена со светом — разные работы. Декорации меняют, не переписывая пьесу.

Эти паттерны ставят стену между **интерфейсом** и **данными с правилами**, чтобы изменение того, как что-то _выглядит_, не ломало то, что оно _делает_.

_Diagram: MVC: пользователь → Controller → Model (данные и правила) → View (что видно)._

#### MVC / MVVM (Model–View–Controller / Model–View–ViewModel)

- **Проблема:** Логика размазана по экранам; поменять дизайн = переписать правила.
- **Идея:** **Model** — данные и правила, **View** — отображение, **Controller** (или **ViewModel**) — клей между ними.
- **Пример:** Django и Rails построены на MVC; мобильные и богатые веб-приложения — на MVVM, где ViewModel держит состояние экрана.
- **Цена:** В больших экранах «клей» разрастается; нужно следить, чтобы логика не утекала во View.
- **Когда брать:** Любое приложение с интерфейсом.
- **Связи:** Это слои **Layered**, взятые для UI.

> **Тест здорового одного приложения:** «Могу ли я поменять то, как это выглядит, или сменить базу — не трогая бизнес-правила?»

> Монолит — это не бардак. Бардак — это монолит без внутренних стен.

## 3. Направление зависимостей

Два паттерна — одна идея: бизнес-правила в центре и ничего не знают про фреймворк, базу и веб. Всё техническое — снаружи и подключается к ядру.

### Hexagonal Architecture — порты и адаптеры

> Игровая консоль со стандартными разъёмами. Игре всё равно, что воткнули — геймпад, руль или аркадный стик; она просто читает «ввод».

Ядро с бизнес-логикой объявляет **порты (ports)** — интерфейсы вроде «сохранить заказ» или «списать деньги». Снаружи **адаптеры (adapters)** реализуют эти порты под конкретную технологию. **Driving adapters** вызывают ядро (HTTP API, CLI, тесты), **driven adapters** вызываются ядром (база, платёжка, почта).

_Diagram: Ядро объявляет порты; адаптеры подключаются снаружи — их можно менять, ядро не заметит._

#### Hexagonal Architecture (Ports and Adapters, гексагональная)

- **Проблема:** Бизнес-логика вросла во фреймворк и базу — её невозможно тестировать и менять.
- **Идея:** Ядро говорит только с портами (интерфейсами); технология живёт в адаптерах.
- **Пример:** Порт `OrderRepository`: в проде адаптер на Postgres, в тестах — список в памяти.
- **Цена:** Больше интерфейсов и файлов; для крошечного CRUD это избыточно.
- **Когда брать:** Есть настоящие бизнес-правила, которые должны пережить смену технологий.
- **Связи:** **Clean / Onion — та же идея**, нарисованная кругами.

### Clean / Onion Architecture — зависимости смотрят внутрь

> Луковица: сердцевина в центре, слои вокруг. Шелуху можно снять, не повредив сердцевину, — а сердцевина от шелухи не зависит.

Тот же принцип в виде кругов. В центре **сущности (entities)**, вокруг **сценарии (use cases)**, дальше адаптеры, снаружи фреймворки и база. Главное правило — **dependency rule**: каждая стрелка зависимости смотрит к центру.

_Diagram: Clean / Onion: внешние круги зависят от внутренних, никогда наоборот._

#### Clean Architecture / Onion Architecture (чистая / луковая архитектура)

- **Проблема:** Смена фреймворка или базы заставляет переписывать бизнес-логику.
- **Идея:** Dependency rule: внутренние круги не импортируют ничего из внешних.
- **Пример:** Правило «счёт больше 10k требует согласования» — обычный класс без импортов веб-фреймворка и ORM.
- **Цена:** Больше слоёв и маппинга данных между ними.
- **Когда брать:** Долгоживущие продукты со сложными правилами.
- **Связи:** Близнец **Hexagonal**; часто живёт внутри модулей **Modular Monolith**.

> **Тест на направление зависимостей:** «Если я сегодня ночью удалю свой веб-фреймворк — сколько бизнес-логики придётся переписать?»

> Фреймворки — это детали. Относись к ним как к обоям, а не как к фундаменту.

## 4. Разделение на много частей

На каком-то масштабе — нагрузки или числа команд — одно приложение перестаёт справляться. Эти паттерны режут систему на независимые части и взамен вручают тебе сеть со всеми её сбоями.

### Microservices — микросервисы

> Фуд-корт: у каждой точки своя кухня, меню и касса. На пиццу налегли — ставят двух поваров; салатной это не нужно.

Система разбита на маленькие **сервисы (services)**: каждый владеет одной бизнес-способностью и **своей базой**, разворачивается и масштабируется отдельно. Сервисы общаются по сети — HTTP или через шину сообщений.

_Diagram: Каждый сервис — свой деплой и своя база; между ними — сеть._

#### Microservices (микросервисы (предок — SOA))

- **Проблема:** Много команд мешают друг другу в одном коде; части системы нагружены очень неровно.
- **Идея:** Отдельные сервисы с отдельными базами и отдельным деплоем.
- **Пример:** Сервисы `orders`, `inventory`, `delivery`; в «чёрную пятницу» масштабируют только заказы и оплату.
- **Цена:** **Распределённая система**: задержки сети, нет простых транзакций между сервисами, сложная эксплуатация и отладка.
- **Когда брать:** Большие команды и неровная нагрузка. Для стартапа из пяти человек — перебор.
- **Связи:** Вырастает из **Modular Monolith**; общается через **Event-driven** и **Queues**; для общих операций нужна **Saga**.

### Serverless — функции по требованию

> Вместо своей машины, которая стоит без дела, ты вызываешь такси и платишь только пока тикает счётчик.

Ты пишешь маленькие **функции (functions)**, а облако запускает их по событию, само масштабирует от нуля до тысяч копий и обратно и берёт деньги за каждый запуск.

_Diagram: Событие → функция запускается столько раз, сколько нужно → результат. Платишь за запуски._

#### Serverless (FaaS, Functions as a Service)

- **Проблема:** Сервер простаивает и стоит денег, а нагрузка приходит рывками.
- **Идея:** Код запускается только на событие; масштабированием занимается облако.
- **Пример:** Загрузили картинку в хранилище → функция делает превью → между загрузками ничего не работает.
- **Цена:** **Cold start** (задержка первого запуска), лимиты по времени, привязка к облаку.
- **Когда брать:** Рваная, событийная работа: обработка файлов, вебхуки, задачи по расписанию.
- **Связи:** Естественно работает в паре с **Event-driven**.

> **Прежде чем дробить:** «Я дроблю, потому что нагрузка или команды правда этого требуют — или потому что „микросервисы“ звучит солидно?»

> Распределённые системы превращают вызовы функций в вызовы по сети. И каждый из них может упасть.

## 5. Как части разговаривают

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

### Request–Response — спросить и ждать

> Заказ у стойки: спросил, стоишь, получил кофе — только потом идёшь дальше.

Клиент отправляет **запрос (request)** и **ждёт ответ (response)**. Это **синхронное** общение: REST, gRPC, запрос в базу.

_Diagram: Пока сервер работает, клиент заблокирован и ждёт._

#### Request–Response (запрос–ответ, синхронный вызов)

- **Проблема:** Нужен ответ прямо сейчас, чтобы продолжить.
- **Идея:** Вызвал → дождался → продолжил.
- **Пример:** Оформление заказа вызывает платёжный API и ждёт подтверждения.
- **Цена:** **Связанность во времени**: если сервер тормозит или лежит, вызывающий тоже застрял.
- **Когда брать:** По умолчанию — когда ответ действительно нужен сразу.
- **Связи:** Противоположность асинхронным **Event-driven** и **Queues**.

### Event-driven Architecture — объяви, а слушатели отреагируют

> Редакция новостей: вышла новость — спорт, погода и реклама реагируют сами. Диктор их не ждёт и даже не знает, кто слушает.

Компонент не вызывает других, а публикует **событие (event)** — факт, который уже случился: «OrderPlaced». Кому интересно, тот подписан и реагирует. Два варианта: **broker** (события расходятся свободно) и **mediator** (координатор ведёт шаги по порядку).

_Diagram: Сервис публикует событие; почта, склад и аналитика реагируют независимо._

#### Event-driven Architecture (событийная архитектура)

- **Проблема:** Один сервис вынужден знать и вызывать всех, кому важно, что что-то случилось.
- **Идея:** Публикуй факт; подписчики реагируют сами и независимо.
- **Пример:** «OrderPlaced» → письмо клиенту, резерв на складе, запись в аналитику.
- **Цена:** Поток трудно отследить и тестировать; события приходят дважды или не по порядку.
- **Когда брать:** Много независимых реакций на одно действие; медленные побочные эффекты.
- **Связи:** Работает поверх **Queues / Pub-Sub**; основа для **Event Sourcing** и **Saga**.

### Message Queue и Pub/Sub — почта между частями

> Почта держит письмо, пока получатель не готов. Ты бросил его в ящик и ушёл; он прочитает, когда проснётся.

**Очередь сообщений (message queue)** или **брокер pub/sub** встаёт между отправителем и получателем, чтобы им не нужно было быть онлайн одновременно. В очереди одно сообщение берёт один **worker**; в **pub/sub** одно сообщение получают все подписчики.

_Diagram: Producer кладёт задачу и уходит; workers забирают задачи, когда свободны._

#### Message Queue / Pub-Sub (очередь сообщений / публикация-подписка)

- **Проблема:** Медленная работа тормозит ответ пользователю; пики нагрузки валят систему.
- **Идея:** Положить задачу в очередь и обработать позже, в своём темпе.
- **Пример:** Тяжёлый отчёт кладут в очередь (RabbitMQ, Kafka, SQS), worker делает его в фоне, сайт остаётся быстрым.
- **Цена:** Результат становится отложенным; нужно думать про повторы и дубли сообщений.
- **Когда брать:** Фоновые задачи, сглаживание пиков, связь между сервисами.
- **Связи:** Транспорт для **Event-driven** и **Microservices**.

### Pipe-and-Filter — конвейер для данных

> Линия розлива: помыть, налить, закрыть, наклеить этикетку. Каждая станция делает одно и передаёт бутылку дальше.

Данные текут через цепочку независимых шагов — **фильтров (filters)**, соединённых **трубами (pipes)**. Каждый фильтр делает одно преобразование.

_Diagram: Данные проходят через фильтры по очереди, как в Unix-пайпе._

#### Pipe-and-Filter (конвейер, pipeline)

- **Проблема:** Сложная обработка данных превращается в одну огромную функцию.
- **Идея:** Разбить на простые шаги, каждый со входом и выходом.
- **Пример:** `grep | sort | uniq`, ETL-задача, компилятор (токенизация → разбор → оптимизация → генерация).
- **Цена:** Плохо подходит, когда шагам нужно возвращаться назад или договариваться.
- **Когда брать:** Работа — ясная последовательность преобразований.
- **Связи:** Шаги часто соединяют через **Queues**.

> **Тест на способ общения:** «Если другая сторона лежит — вызывающему ждать, падать или жить дальше и догнать потом?»

> Синхронно — это телефонный звонок. Асинхронно — это письмо.

## 6. Паттерны вокруг данных

Эти паттерны не про коробки, а про то, как ты пишешь, читаешь и хранишь правду.

### CQRS — раздельные модели записи и чтения

> В библиотеке быстрый каталог для поиска и отдельная задняя комната, где книги расставляют по полкам. Поиск заточен под одно, хранение — под другое.

**CQRS (Command Query Responsibility Segregation)** разделяет **модель записи** — **команды (commands)**, которые меняют данные, — и **модель чтения** — **запросы (queries)**, которые их достают. Каждую можно оптимизировать и масштабировать отдельно.

_Diagram: Команды идут в модель записи, запросы — в отдельную модель чтения; между ними синхронизация._

#### CQRS (Command Query Responsibility Segregation)

- **Проблема:** Одна модель данных плохо подходит и для сложной записи, и для быстрого чтения.
- **Идея:** Две модели: запись — со всеми правилами, чтение — заранее посчитанные «витрины».
- **Пример:** Дашборд читает из денормализованной витрины, заказы пишутся в транзакционную базу.
- **Цена:** Две модели надо синхронизировать; чтение может слегка отставать (**eventual consistency**).
- **Когда брать:** Чтений кратно больше записей, или они очень разные по форме. Не по умолчанию.
- **Связи:** **Часто в паре с Event Sourcing**: события из лога строят модель чтения.

### Event Sourcing — хранить историю, а не состояние

> Банк хранит не только твой баланс, а каждый приход и расход. Баланс — лишь их сумма. Потеряешь его — пересчитаешь по журналу.

Вместо того чтобы перезаписывать текущее состояние, ты хранишь **поток событий (event log)**, только дописывая в конец. Текущее состояние получается **проигрыванием (replay)** событий.

_Diagram: Журнал событий → проигрывание → текущее состояние._

#### Event Sourcing (событийное хранение)

- **Проблема:** Нужно знать не только «что сейчас», но и «как к этому пришли».
- **Идея:** Источник правды — журнал событий; состояние вычисляется из него.
- **Пример:** Счёт: «открыт, +100, −30, +5» вместо «баланс: 75» — полный аудит и ответ на «как было в прошлый вторник?».
- **Цена:** Запросы «что сейчас» сложнее; события нельзя редактировать — история навсегда.
- **Когда брать:** Финансы, аудит, сложные бизнес-процессы.
- **Связи:** Почти всегда с **CQRS**; естественно сочетается с **Event-driven**.

### Saga — длинная операция, которую можно отмотать

> Бронируешь поездку: рейс, отель, машина. Машина сорвалась — отменяешь отель и рейс. Единой кнопки «отменить всё» нет, отматываешь по шагу.

Когда одно бизнес-действие проходит через несколько сервисов со своими базами, одну общую транзакцию сделать нельзя. **Saga** — цепочка **локальных транзакций**; если шаг падает, запускаются **компенсирующие действия (compensations)**, отменяющие предыдущие шаги.

_Diagram: Шаг 3 упал → компенсации отменяют шаги 2 и 1 в обратном порядке._

#### Saga (сага, распределённая транзакция с компенсациями)

- **Проблема:** Одна операция затрагивает несколько сервисов, и нет общей транзакции.
- **Идея:** Шаги по очереди, у каждого — «отменяющий» шаг на случай сбоя.
- **Пример:** Создать заказ → зарезервировать товар → списать с карты; списание упало — освободить товар, отменить заказ.
- **Цена:** Каждому шагу нужна компенсация; между шагами данные временно несогласованы.
- **Когда брать:** Бизнес-операции поперёк **Microservices**.
- **Связи:** Нужна **Microservices**; шаги часто координируют через **Event-driven**.

> **Вопрос о правде в данных:** «Где источник правды — текущее значение или история, которая его породила?»

> Транзакция — это один атом намерения. Когда он охватывает сервисы, атом приходится собирать самому.

## 7. Особые формы

Эти паттерны существуют ради одной конкретной боли. Тянись за ними, когда у тебя именно эта боль — и ни секундой раньше.

### Microkernel — маленькое ядро и плагины

> Дрель: один мотор и дюжина насадок. Дрель та же — меняешь насадку под задачу.

Минимальное **ядро (core)** даёт основу, всё остальное приходит **плагинами (plugins)**, которые подключаются к ядру и не зависят друг от друга.

_Diagram: Ядро и подключаемые плагины — как редактор кода и его расширения._

#### Microkernel (Plugin Architecture, плагинная архитектура)

- **Проблема:** Функций много, они меняются и у разных клиентов разные.
- **Идея:** Стабильное маленькое ядро + независимые плагины.
- **Пример:** VS Code и браузеры с расширениями; страховая система, где правила региона — плагин.
- **Цена:** Нужно аккуратно спроектировать API для плагинов и их совместимость.
- **Когда брать:** Продукт-платформа, кастомизация под клиентов.
- **Связи:** Плагины часто подключаются через порты, как в **Hexagonal**.

### Space-based Architecture — данные в памяти без узкого места

> Стадион с двадцатью кассами, у каждой своя копия схемы зала, — вместо одной кассы с огромной очередью.

Когда единственная база становится узким местом под огромной нагрузкой, работу делят много **processing units**, каждый держит данные в памяти. Память синхронизируется между ними (**data grid**), а в базу данные пишутся позже, асинхронно.

_Diagram: Нагрузка распределяется по узлам с данными в памяти; база — уже не узкое место._

#### Space-based Architecture (архитектура на основе пространства (tuple space))

- **Проблема:** Одна база не выдерживает пиковой одновременной нагрузки.
- **Идея:** Данные в памяти многих узлов, синхронизация между ними, запись в базу — потом.
- **Пример:** Флеш-распродажа или онлайн-аукцион с валом одновременных ставок.
- **Цена:** Очень сложно и дорого; риск потери данных между памятью и базой.
- **Когда брать:** Только при по-настоящему огромной и рваной конкурентной нагрузке.
- **Связи:** Использует кеширование и асинхронную запись, как **Queues**.

### Peer-to-Peer — без центра

> Ужин в складчину: каждый и повар, и гость. Ни ресторана, ни официанта — группа кормит себя сама.

Узлы — **peers** — общаются напрямую, без центрального сервера. Каждый одновременно и клиент, и сервер.

_Diagram: Каждый узел связан с другими напрямую; центрального сервера нет._

#### Peer-to-Peer (P2P, одноранговая сеть)

- **Проблема:** Центральный сервер — дорогая и уязвимая точка отказа.
- **Идея:** Участники сами делят нагрузку и данные между собой.
- **Пример:** BitTorrent: каждый, кто скачивает, ещё и раздаёт — чем больше людей, тем сильнее сеть.
- **Цена:** Трудно обеспечить согласованность, безопасность и контроль.
- **Когда брать:** Раздача файлов, блокчейн, устойчивость без центрального хоста.
- **Связи:** Противоположность клиент-серверным формам вроде **Request–Response**.

> **Тест на экзотический паттерн:** «А есть ли у меня та редкая проблема, под которую эта форма создавалась?»

> Экзотические паттерны — лекарство, а не витамины. Принимай под поставленный диагноз.

## 8. Как выбирать

Паттерны — словарь, а не меню с одним блюдом. Реальные системы сочетают несколько, а самый мудрый ход часто самый простой.

### Паттерны связаны между собой

> Дом сразу использует несущие стены, водопровод и проводку — не «один истинный паттерн строительства».

Паттерны не живут поодиночке. Модульный монолит **вырастает** в микросервисы; микросервисам **нужны** события, очереди и саги; Hexagonal и Clean — **одна идея**; CQRS и Event Sourcing **ходят парой**.

_Diagram: Главные связи между паттернами курса._

Реальная система может быть модульным монолитом снаружи, Clean Architecture в каждом модуле, Request–Response для интерфейса, событиями для медленных побочных эффектов и очередью перед тяжёлой задачей. Вопрос не «какой паттерн», а **«какие паттерны и где»**.

### Начинай с самой простой формы

> Под домик не заливают фундамент для стадиона.

Почти любая система должна начинаться как **Modular Monolith** и **заслуживать** свою сложность. Microservices, CQRS, Event Sourcing, Space-based — ответы на проблемы масштаба и размера команды, которых у тебя может никогда не быть. **Самая дешёвая распределённая система — та, которую ты не построил.**

#### Прежде чем выбрать паттерн

- **Какую повторяющуюся проблему решает эта форма?** Назови одним предложением.
- **Есть ли у меня эта проблема сейчас** — или я гадаю про будущее?
- **Чего это стоит?** В задержках, эксплуатации, сложности, деньгах.
- **Какой самый простой паттерн ещё сработал бы?** Начни с него.
- **Могу ли я взять это позже**, когда боль реально проявится?

#### Признаки, что ты переусложнил

- **Сервисов больше, чем инженеров.**
- Одно действие пользователя задевает **пять сервисов и две очереди**.
- **CQRS или Event Sourcing** появились раньше, чем проблема чтения или аудита.
- **Никто в команде** не нарисует систему по памяти.
- Паттерн выбран, **потому что так делают большие компании**.

## Шпаргалка: все 17 паттернов

### Устройство одного приложения

- **Layered** (слоистая, n-tier): Код по этажам: представление → логика → данные → база. Запрос идёт сверху вниз.
- **Modular Monolith** (модульный монолит): Одно приложение, разрезанное на модули с чёткими интерфейсами. Лучший дефолт.
- **MVC / MVVM** (Model–View–Controller): Стена между интерфейсом и данными с правилами.

### Направление зависимостей

- **Hexagonal** (Ports and Adapters): Ядро объявляет порты, технологии подключаются адаптерами.
- **Clean / Onion** (чистая / луковая): Круги, все зависимости смотрят к центру (dependency rule).

### Разделение на части

- **Microservices** (микросервисы): Отдельные сервисы со своими базами и деплоем. Цена — распределённая система.
- **Serverless** (FaaS): Функции по событию, облако масштабирует, платишь за запуск.

### Как части разговаривают

- **Request–Response** (синхронный вызов): Спросил и ждёшь ответа. Просто, но связывает во времени.
- **Event-driven** (событийная): Публикуешь факт, подписчики реагируют сами.
- **Message Queue / Pub-Sub** (очередь сообщений): Задача ждёт в очереди, пока worker не освободится.
- **Pipe-and-Filter** (конвейер): Данные проходят через цепочку простых шагов.

### Данные

- **CQRS** (Command Query Responsibility Segregation): Отдельные модели для записи и чтения.
- **Event Sourcing** (событийное хранение): Храним журнал событий; состояние — его проигрывание.
- **Saga** (сага): Шаги через несколько сервисов + компенсации при сбое.

### Особые формы

- **Microkernel** (плагинная архитектура): Маленькое ядро и независимые плагины.
- **Space-based** (data grid в памяти): Данные в памяти многих узлов, база не узкое место.
- **Peer-to-Peer** (P2P): Узлы общаются напрямую, без центра.

> Лучшая архитектура — самая простая, что переживает твои реальные требования, и ни одним паттерном больше.

Конец экспресс-курса · 8 глав · 17 паттернов

Дальше — практика. Каждый паттерн разворачивается в книги: «Software Architecture Patterns» Марка Ричардса, «Fundamentals of Software Architecture», «Designing Data-Intensive Applications», «Building Microservices». Но прежде чем брать любой паттерн — назови свою проблему. Паттерн — это ответ; проблема — вопрос, который его заслуживает.
