Эргономичному подходу 5 лет!

February 22, 2025

5 лет назад, в 11:03 22 февраля 2020 года я нарисовал эту картинку и начал работу над Эргономичным подходом:

2025 02 19 09 38 38

За эти годы Эргономичный подход многое потерял (в основном функциональный вайб и юношеский максимализм) и многое нашёл (в основном конкретные инструменты и боевые шрамы) и я хочу отметить этот день небольшой ретроспективой Эргономичного подхода.

Февраль 2020 года: точка отсчёта

Точкой старта ЭП были следующие правила:

  • Ввод-вывод не может содержать в себе бизнес-логику - они связываются в юзкейсе
  • Изменяемые поля запрещены
  • Изменяемые локальные переменные запрещены
  • Код юзкейса (workflow, операция) должен быть прямой как железная дорога - с цикломатической сложностью, не более единицы;
  • Весь ввод-вывод должен быть виден на уровне юзкейса;
  • Тесты должны работать с системой в точности так, как это делают клиенты. В том числе находиться в отдельном процессе;
  • Моки запрещены;
  • Отношение 1-ко-многим нельзя использовать никогда;
  • Пакетировать по слоям запрещено;
  • Выбрасывать исключения запрещено.

Июнь-июль 2020 года: Project Daniel

Project Daniel был проектом по рефакторингу большой функции в большом монолите. По технико-историческим причинам, в этом проекте невозможно было применить все правила ЭП, однако основные идеи - неизменяемую модель данных, разделение и бизнес-логики и тестирование бизнес-логики проверить удалось.

Июнь-июль 2020 года: Project T

Параллельно с Project Daniel я делал Project T - небольшой сервачёк который должен был связать бота заказчика для торговли на бирже криптовалют и мобильное приложение для отслеживания и управления этим ботом. И это был первый проект, сделанный на 100% по ЭП. В этот проект (во многом по мотивам Project Daniel) я заходил с установкой, что One-to-Many - это квинтэссенция зла и его всегда надо заменять на Many-to-One. Однако в процессе реализации этого проекта стало очевидно, что не всё так просто и этот проект положил начало идеи One-To-Few

Январь-апрель 2021 года: Project L

Следующим был Project L - небольшой проектик для проверки бизнес-гипотезы большого монолита, который оформлялся отдельным сервисом. И этот проект уже сильно продвинул ЭП:

  • Это был первый проект, который я сделал на Spring Data Relational - на тот момент это был ещё отдельный Spring Data R2DBC
  • В этом проекте начало оформляться то, что в итоге превратилось в Диаграмму эффектов и подход к декомпозиции приложений на её основе.
  • Тут же стало понятно что не каждый отдельный кусочек вывода должен быть виден в юзкейсе, а только io на соответствующем уровне абстракции. В частности в этом проекте буквально на каждый запрос к основной системе мог прилететь обновлённый аутентификационный токен, который по определённым причинам надо было сохранить в БД. И быстро стало очевидно, что все эти приседания с токенами в коде юзкейсов - дичь. Поэтому их пришлось спрятать внутрь клиента внешней системы - первого сложного ресурса в ЭП-программах:)

Но в Project L был и тупиковый путь - этот проект я сделал по (почти) честной чистой архитектуре, у меня юзкейсы и модель данных жили в отдельном модуле, который не зависел от спринга. Поэтому, например, в модуле домена мне пришлось завести собственную абстракцию транзакции. А ещё завести такую дичь как interface MyRepoSdrImpl : MyRepo. Но в одном месте я дал слабину - сущности были вытащены в ещё один модуль, где была implementation (не подтягиваемая транзитивно) зависимость от SDR2DBC, из которой я тянул аннотации. Чтобы хотя бы на уровне моделей эту же дичь не повторять.

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

Июнь 2021 - январь 2022 года: Project Barcoder

Project Barcoder был уже относительно большой проект внутренней системы большой Российской корпорации.

Я его так же сделал по почти честной чистой архитектуре, но чуваки, которые принимали его на саппорт открыли мне глаза, что это полная дичь и основным изменением в ЭП по результатам Project Barcoder стал отказ от чистой архитектуры.

Так же в этом проекте я решил запускать приложение внутри тестов и…​ Они не стали хрупкими

Декабрь 2021 - август 2022 года: Кэмп

Проект Кэмп стал площадкой для обкатки диаграммы эффектов и алгоритма её декомпозиции.

Февраль 2022 - май 2022 года: Geoservices

В Geoservices я продолжил полировать диаграмму эффектов и это был первый проект разбитый на модули по диаграмме эффектов, но пока что на интуитивном уровне.

Июнь 2022 - январь 2024 года (для меня): Project E

Проект Э стал самым большим к текущему моменту проектом, сделанным по ЭП.

И его основная заслуга в том, что он подсветил проблемы ЭП:

  • объектно-ориентированная декомпозиция, получающая по алгоритму декомпозиции диаграммы эффектов имеет ряд проблем;
  • в ЭП нет ответа как структурировать код тестов.

В результате Проект Э заложил основу для Эргономичной архитектуры (в особенности разделение прикладного кода на слой приложения и домена) и Эргономичной архитектуры тестов.

Сентябрь 2022 - текущий момент: Trainer Advisor

Trainer Advisor является в основном площадкой для обкатки идей, возникших в ходе коммерческой разработки. В частности именно на TA я в первый раз обкатал идеи Эргономичной архитектуры и в, особенности, Эргономичной архитектуры тестов.

Но и собственный вклад ТА тоже сделал:

  • При работе над TA я обнаружил, что RestAssured запускается 1 секунду и это меня подтолкнуло посмотреть на Spring WebTestClient;
  • При работе над TA я осознал, что обработку сбоев в работе инфраструктуры (Postgres, в частности) протестировать без моков чрезвычайно сложно и допустил использование моков в таких случаях;

Май 2024 года: Project Mariotte

Работа над Project Mariotte - демо-проектом - помогла мне существенно продвинуть Эргономичную архитектуру, а так же проверить гипотезу, что в случае Spring WebTestClient переключение между работой через MockMVC и HTTP достаточно безболезненное и перейти на применение MockMvc в связке с WebTestClient по дефолту.

Июнь 2024 - текущий момент: Project R

Project R - самый сложный на текущий момент проект, сделанный по ЭП. Трудоёмкость проекта к текущему моменту составляет порядка одного человеко года и при том в нём чуть больше 10К строк кода с тестами и 10 табличек.

Для сравнения, в Project E за тот же человеко-год мы нагенеряли 40К строк кода и 60+ таблиц.

И как следствие Проект Р существенно продвинул ЭП:

  • Подтвердил жизнеспособность Эргономичной архитектуры;
  • Подарил идею доменных операций;
  • Подтвердил жизнеспособность тестов на MockMVC;
  • Подарил идею пресетов фикстур для сетапа фикстуры из сложных графов объектов;
  • Подарил гайдлайн обработки ошибок и вернул в милость исключения.

Будущее

Для того чтобы успеть опубликовать пост ровно в 11:03, мне осталось буквально несколько минут, поэтому про будущее я напишу как-нибудь в другой раз:)