← назад к разделу

В классической трёхслойной архитектуре слои идут сверху вниз: UI → бизнес-логика → слой доступа к данным. Зависимости направлены вниз: бизнес-логика зависит от слоя данных, тот — от базы. В итоге домен намертво сцеплен с конкретной СУБД и фреймворком: нельзя протестировать логику без поднятой базы, а смена хранилища тянет правки в бизнес-код. Луковая архитектура (Onion) переворачивает это: в центре — чистый домен, а всё инфраструктурное вынесено наружу и зависит от центра, а не наоборот.

Что такое луковая архитектура

Представьте луковицу в разрезе: концентрические кольца, в самом центре — доменная модель. Каждое кольцо может зависеть только от колец, которые внутри него. Внешние кольца знают о внутренних, а внутренние о внешних — нет.

Что на схеме: стрелки зависимостей идут только внутрь, к домену.

diagram

Кольца от центра наружу:

  • Доменная модель — сущности и value-объекты с бизнес-правилами. Чистый код: никаких импортов БД, HTTP, фреймворка.
  • Доменные сервисы — логика, которая охватывает несколько сущностей и не помещается в одну.
  • Сервисы приложения (use cases) — оркестрация: принять запрос, дёрнуть домен, сохранить результат.
  • Внешнее кольцо — всё остальное: база, очереди, внешние API, веб-контроллеры, конфигурация фреймворка.

Правило зависимостей

Главное правило одно: зависимости направлены только внутрь. Внешнее кольцо знает о внутренних, внутренние о внешнем — нет.

Как это возможно технически, ведь сервису приложения нужно сохранить данные в базу (внешнее кольцо)? Через инверсию зависимостей: внутреннее кольцо объявляет интерфейс (например OrderRepository), а внешнее кольцо его реализует (PostgresOrderRepository). Домен зависит от интерфейса, который сам же и определил; конкретная реализация живёт снаружи и подставляется при сборке приложения. Так стрелка зависимости разворачивается внутрь, хотя поток данных идёт наружу.

Прямое следствие — домен тестируется без базы и фреймворка: интерфейсы подменяются заглушками.

Onion, гексагональная и Clean Architecture — одно семейство

Это все варианты одной идеи: держать домен чистым и развернуть зависимости к центру. Различается в основном словарь и акценты:

  • Гексагональная (Ports & Adapters) — домен в центре, вокруг него порты (интерфейсы) и адаптеры (реализации). Подчёркивает симметрию входящих и исходящих границ.
  • Луковая (Onion) — те же зависимости-внутрь, но поданы как концентрические кольца с доменной моделью в самом центре; акцент на слоистости.
  • Clean Architecture — то же самое кольцами «entities → use cases → interface adapters → frameworks» с тем же правилом зависимостей.

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

Когда применять

Луковая архитектура оправдана, когда домен богатый и живёт долго, инфраструктур несколько (БД + очередь + внешние API), а тестируемость важна. Для простого CRUD-сервиса без сложных правил концентрические кольца — избыточная церемония: получится много интерфейсов ради одного-двух вызовов.

Коротко

  • Луковая архитектура — концентрические кольца с доменной моделью в центре; зависимости направлены только внутрь.
  • Домен не знает о базе, HTTP и фреймворке — снаружи подставляются реализации интерфейсов, объявленных внутри (инверсия зависимостей).
  • Главный выигрыш — домен тестируется без инфраструктуры, а смена БД/фреймворка не задевает бизнес-логику.
  • Onion, гексагональная и Clean Architecture — одно семейство; разница в словаре, не в сути.
  • Для простого CRUD — избыточно; применяйте при богатом, долгоживущем домене.

Что почитать дальше

  • Гексагональная архитектура — тот же принцип в варианте ports & adapters, с реализацией по шагам.
  • CQRS — разделение команд и запросов поверх чистого домена.
  • Domain-Driven Design — что именно живёт в центре луковицы.