Нередко в продакшн можно встретить простую и понятную (на первых порах) архитектуру. Это частный случай разделения на базовые слои (ntier в действии):

  • контроллер
  • сервис
  • репозиторий
  • ORM

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

Подход рабочий 👍

И в простых случаях, особенно если мы говорим про небольшие сервисы, проблем никаких нет. Само собой — до поры до времени, пока не появляются кейсы вроде:

  • Решили сменить ORM 🔄
  • Решили заменить axios/got на fetch 🌐
  • Покрыть всё тестами 🧪

И вот тут начинается интересное.

Внезапно выясняем:

  • доменные сущности с декораторами ORM
  • сервисы знают про конкретную БД
  • тесты поднимают реальную SQLite
  • axios используется в сервисах, обработке ошибок и так далее

Меняется библиотека → переписываем полпроекта.
Или ещё хуже — библиотека начинает управлять всей архитектурой

С тестированием тоже беда. Хотим протестировать регистрацию, а получаем:

  • поднятие БД
  • поднятие HTTP
  • «проще» написать интеграционный тест вместо unit

То есть тестируем уже не бизнес-логику, а весь сценарий вместе с зависимостями целиком.

Вот тут и появляется необходимость пересмотреть подход к архитектуре.
Clean Architecture становится одним из возможных решений 🚀