Эргономичный код
796 subscribers
76 photos
3 videos
20 files
384 links
Канал о разработке поддерживаемых бакэндов - про классическую школу TDD, прагматичное функциональное программирование и архитектуру и немного DDD.

Группа: https://t.me/+QJRqaHI8YD

https://azhidkov.pro
Download Telegram
ss-bbom.png
15.6 KB
Привет!

Мне тут попался проект с пакетированием по слоям представляющий из себя сферический Big Bull of Mud в вакууме.

Проект хорош тем, что в пакетах верхнего уровня нет ничего лишнего, но я утверждаю, что подобный подход к пакетированию неминуемо ведёт к такой архитектуре

P.S.
На диаграмме - матрица зависимостей, красным обозначены циклы в зависимостях между модулями, в здоровом проекте их быть не должно и матрица должна быть нижнетреугольной.

#case@ergonomic_code
image_2022-05-13_18-16-19.png
13.9 KB
Привет!

Ну скажите же, эта структура намного понятнее, чем свалки из controllers, services и т.д.

Возвращаюсь спустя полгода к проекту, сделанному по ЭП и нарадоваться не могу.

#case@ergonomic_code #why_ergo_approach@ergonomic_code #ergo_approach@ergonomic_code
👍1
Привет!

Надоело мне мурыжить пост о построении диаграммы реального проекта, поэтому я волевым усилием его быстренько добил и с радостью представляю вашему вниманию:)

А дальше в серии будет два спиноффа - "Сцепленность" и "Объектный дизайн, как средство снижения сцепленности". Обе концепции у меня самого ещё не до конца разложены по полочкам, поэтому не берусь спрогнозировать сколько мне времени мне потребуется на эти посты.

После чего я смогу вернуться к третьему посту серии о применении диаграммы эффектов для объектной декомпозиции системы на модули. Но боюсь как бы это не осенью было.

#effects_diagram@ergonomic_code #case@ergonomic_code #project_geoservices@ergonomic_code #posts@ergonomic_code
2
Привет

Сегодня у нас рубрика "Мои факапы".

Есть у меня один проект, где флоу создания одной из сущностей такой:
1) непривилегированный пользователь создаёт сущность
2) привилегированный пользователь её одобряет или отклоняет

ну и плюс привилегированный пользователь может её редактировать в любой момент.

я уже подробностей дизайна не помню, но с одной стороны у меня вроде были какие-то трудности с проектированием урла для аппрува (хотя щяс ретроспективно не понимаю, что за трудности), а с другой стороны чёт захотелось поэкономить методы.

В итоге сейчас у нас есть метод PATCH /entity/{id}
который принимает сущность с 15 нуллабельными полями. используется двумя способами - либо присылаются все 15, либо 1 - approved

И есть метод POST /entity
С теми же 15 полями. но не нуллабельными.

И хз что с этим добром теперь делать.

Щяс я уже думаю, что надо было не выпендриваться, обновление делать через PUT, а аппрув через PATCH /entity/{id}/approved или POST /entity/{id}/(approve|reject)

А от PATCH-а сущностей держаться подальше до тех пор, пока требования к стенке не припрут - в языках со статической типизацией это боль

И заодно наткнулся на прикольную штуку JSON-P - когда мне придётся в следующий раз делать патч, я так пойду, а не через типизированную нуллабельную ДТОшку

#case@ergonomic_code #project_camp@ergonomic_code #http_api@ergonomic_code #rest_api@ergonomic_code #tools@ergonomic_code
Привет!

Я сейчас ковыряюсь с легаси проектом, и мне второй месяц не даёт покоя то, что оригинальные авторы запилили RPC over RabbitMQ.

Накатал микропост с разбором этого подхода.

За одно апдейт по статусу постов - написал первый черновик поста "Эргономичный подход к ООП и ООД", который станет обоснованием к посту с методикой декомпозиции на базе диаграммы эффектов.

Но теперь его надо будет полировать и думаю месяц на это в лёгкую уйдет. С учётом того, что я не на 100% уверен, что хочу связываться термином ОО, в силу его расплывчатости

#project_e@ergonomic_code #case@ergonomic_code
👍1
image_2022-07-29_11-01-13.png
208.5 KB
Привет!

Продолжаю в фоне размышлять о том является ли RPC over RabbitMQ антипаттерном, нагенерял ещё пару мыслей, делюсь.

Нетиповое решение
Я сейчас читаю Building Microservices (кстати, очень крутая книга - в первой же главе пишет что МС это боль и надо начинать с монолита) и там типовым решением для синхронного стиля пишут HTTP/RPC (картинка)

Стримминг
В рамках работы над этим чудо проектом в один момент показалось, что мне нужен стриминг большого объёма данных из одного МС в другой. В итоге обошлось но если бы не обошлось, то на HTTP я бы это без вопросов сделал, а с очередью бы ой вышел

Разделение АПИ
Ещё подумал, что плюсом такого решения является явное разделение АПИ на публичное и приватное. Но на HTTP это тоже можно провернуть (сам не пробовал)

В общем я пока придерживаюсь мнения, что это всё-таки ошибка была.

#case@ergonomic_code
Привет!

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

#effects_diagram@ergonomic_code #ergo_approach@ergonomic_code #project_geoservices@ergonomic_code #case@ergonomic_code
🔥6
Привет!

Чем задро люди, нашедшие работу по душе занимаются на праздничных днях? Правильно - переводят проекты на Spring Boot 3.

И я, будучи таким человеком, перевёл Проект Э на Spring Boot 3.
За пару месяцев работы в 3.5 лица мы нагенеряли довольно дофига кода - 300 *.kt-файлов и тем не менее переезд мне дался довольно легко. Сделал я его часа за 2, изменения внёс следующие:

1) очевидным образом, обновил версии
2) заменой по проекту поправил javax.* -> jakarta.*
3) Поменял com.github.tomakehurst:wiremock-jre8:2.35.0 -> com.github.tomakehurst:wiremock-jre8-standalone:2.35.0. Без этого были проблемы со спекой сервлетов, что ли
4) В конфиге Spring Security заменой по файлу поправил antMatchers -> requestMatchers
5) Руками поудалял ConstructorBinding
6) Больше всего времени ушло на то, чтобы реанимировать вытягивание доков к эндпоинтам в сваггере из котлин доков. Для этого пришлось руками добавить зависимость runtimeOnly("com.github.therapi:therapi-runtime-javadoc:0.15.0"), а допетрить до того, что этот джарник пропал из зависимостей (без ошибок) пришлось самостоятельно
7) всё. Все 100+ тестов (преимущественно пользовательских/внешних/функциональных/е2е) прошли, приложение благополучно задеплоилось на тестовый стенд. Но его ещё не тестили (почему-то), так что может что-то ещё вылезет. Если вылезет - напишу

Наверное, мне сильно помогло то, что проект я заводил за месяц до релиза Бута 3 и проект у меня был на Буте 2.7.4. Я на самом деле даже попытался сразу стартануть на бете Бута 3, но тогда не получилось завести то ли сваггер целиком, то ли вытягивание котлин доков - круто что уже через месяц после релиза это всё допилили.

При всём моём противоречивом (но всё более положительном в последнее время) отношении к Spring - они реально делают штуку, которая just works (tm).

#spring@ergonomic_code #project_e@ergonomic_code #case@ergonomic_code
👍8
Привет!

По посту с декомпозицией пока особых новостей нет и не будет до JPoint-а, поэтому пока накатал микропост с описанием опыта внедерния тулов статического анализа кода (Detekt, Kover, ArchUnit) в Проект Э.

#posts@ergonomic_code #tools@ergonomic_code #case@ergonomic_code
Привет!

Ретро проекта Э идёт прям тяжело (тупо прокрастинирую его), поэтому решил написать микроретро очередного релиза.

В этом релизе, мы среди прочего сделали две большие штуки:

. Реализовали поддержку множества сессий пользователей - 73 файла, ~1200 строк изменений (ввели понятие сессии и привязали рефреш-токен к ней, а не пользователям. Плюс сделали бесшовную миграцию токенов);
. Серьёзно отрефакторили модуль наблюдения, поправив логические и технические ошибки в изначальной модели - 129 файлов, ~2300 строк изменений.

Ещё хочу напомнить, что месяц назад у нас в проекте всего было 23,944 строк кода и 730 классов.
То есть в этом релизе релизе мы потрогали процентов 15 всей кодов базы.

При этом:

. Багов, найденных командой QA за 3 дня тестирования релиз-кандидата - 0 (ноль);
. Багов, найденных заказчиком и пользователями за 5 дней использования релиза - 0 (ноль);
. Багов, найденных разработчиком по коду после мёржа в мастер - 1 (один);

Лично я считаю это выдающимся достижением.

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

#why_ergo_approach@ergonomic_code #ergo_testing@ergonomic_code #project_e@ergonomic_code #case@ergonomic_code
👍2🔥2👌2
Привет!

Потока сознания пост

У нас тут в Проекте Э был аццкий баг на андроиде. Который заключался в том, что приложение случайным образом переставало подключаться к девайсу по блютузу. Угробили на него кучу времени, сил, денег, нервов, подключились всех кого можно включая меня. В результате фикс получился в 10 символов.

Изначальный код был примерно такой:
scanner.startScan(filters, settings)
.filter { foundDevices->
foundDevices.map { address }
.contains(address)
}
.take(1)

Видите баг? Фильтр мапит список на переменную, а потом проверяет что он содержит эту переменную. Очевидно он срабатывал для любого не пустого списка. Добавили в маппинг it.device.address и всё заработало. Я до сих пор не понимаю как - если есть эксперты по андроиду/бле - напишите, пожалуйста:)

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

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

Соответственно мысль №1 - хорошие тесты должны проверять предположения разработчика относительно кода. Например, сохранение сущности значит, что её потом можно достать по иду - вот это и надо проверять. А не то что ид обновился, или что был вызван метод репоза.

Отсюда мысль №2 - моки вносят дополнительный слой предположений. Стабая что-то, разработчик предполагает что вернёт за стабанный код. И может облажаться. Мокая и верифицируя что-то, разработчик предполагает что замоканный код пережуёт то, что разработчик ему дал и породит нужный разработчику эффект. И так же может облажаться.

Я не думаю что возможно (и экономически целесообразно) жить и кодить вообще без предположений и вообще все предположения проверять. Но рефлексировать на эту тему - точно хорошее упражнение.

#case@ergonomic_code #project_e@ergonomic_code #ergo_testing@ergonomic_code
👍3
Привет!

Накатал микропост о том как мы руками делали потоковый джоин двух БД для админки в Проекте Э.

Если кто-то на будущее научит меня как это можно было сделать быстрее и проще - буду благодарен:)

#case@ergonomic_code #project_e@ergonomic_code
🔥4👍2
Привет!

На денёк задержался, но это потому что у меня были очень интересные приседнания с тестами в эргономичном стиле - может после отпуска расскажу:)

И так, та-да-да, микропост с результатами анализа Jira Проекта Э.

Пост оказался микро только с точки зрения полировки, а по объёму - вполне себе приличный пост, поэтому сразу ТЛДР:

1) Мы действительно стали работать в два раза быстрее и допускать в два раза меньше багов
2) Я получил дополнительное подтверждение вцелом очевидным вещам:
2.1) Первый год разработки на микросервисах дороже разработки на монолите. Минимум на 30%;
2.2) Автоматизация тестирования снижает количество багов и трудозатрат на их устранение. Минимум в два раза;
2.3) Мотивация команды имеет огромное влияние на трудозатарты. От 30% дополнительных трудозатрат в случае низкой мотивации.

#posts@ergonomic_code #case@ergonomic_code #why_ergo_approach@ergonomic_code #project_e@ergonomic_code
🔥6
Привет!

Сегодня у меня будет три топика.

Фидбэк по опросу

На той неделе сначала заболел ребёнок и в сад не ходил, потом я от него заразился и тоже в сад не ходил, поэтому припозднился с фидбэком по опросу.

Итак, фидбек.
Во-первых, спасибо всем проголосовавшим.
Во-вторых, вижу, что тема актуальная, поэтому посту быть.
В-третьих, я учту результаты опроса и чуть подробнее распишу оценку, продажу, планирование, модель ветвтеления и техсложности, а деплой наборот опишу вкратце.
В-четвёртых, есть два голоса за "другое", но без комментариев - у вас всё ещё есть возможность написать, о чём вам было бы интересно узнать, так как у меня новых идей не появилось.

Новый микропрост

На выходных я пропрокрастинировал пост с ретро Проекта Э микропостом (опять же по степени полировки, а не объёму) с описанием решения потенциального "сложного случая" при декомпозиции диаграммы эффектов новой интеграции в Проекте Э.
Ну или аннотация привлекательная для более широкой аудитории - написал микропост с алгоритмом принятия решения о том, в какой класс или микросервис поместить операцию, которая в равной степени зависит от двух классов/микросервисов.

Пост с ретро Проекта Э

Попробую проверить расхожее мнение о том, что публичное обещание помогает в решении задач, которые никак не получается решить. Итак - торжественно клянусь, что с завтрашнего дня я буду заниматься постом с ретро минимум 15 минут в день и каждый день в комментариях к этому посту буду писать о своём прогрессе (ну или о непреодолимых обстоятельствах, которые сложились так, что не было никакой возможности уделить этой работе хотя бы 15 минут).

Текущее состояние поста следующее:
1. В посте есть 3500 слов примерно на 20-25 минут чтения
2. Осталось расписать - техсложности, факапы в проде, деплой, итоговые цифры
3. После чего будет скорее всего долгий и мучительный процесс полировки, который среди прочего будет включать:
3.1 Более глубокое раскрытие "популярных" тем
3.2 Добавление в каждый раздел подраздела "Полезняшки" - что вы себе сможете утащить из моего опыта.

#posts@ergonomic_code #project_3@ergonomic_code #case #effects_diagram@ergonomic_code
👍3
Привет!

У меня для вас снова поучительная история про тесты.

У нас есть эндпоинт выдачи списка лекарств за разработкой которого я не много не доглядел и там разработчик не сделал сортировку. Этот список год не менялся и изначально данные в него внесли в правильном порядке, поэтому никто не замечал проблему.

А тут поменяли и ой.

И я пошёл добавлять сортировку своими мозолистыми руками.
Добавил, думаю надо тестом покрыть, покрыл, думаю надо увидеть как он превращается из красного в зелёный, сломал продовый код, а тест прошёл.
Смотрю - прошёл по той же причине, что и в проде год проблемы не было.

Ну думаю и ладно, чему там не работать, закоммитал, запушил, вмёржил вмастер.

Подтягиваю, мастер в ветку где это надо - а она не собирается О_О Тест не проходит. Потому что данные поменялись. А я продовый код не вернул перед коммитом 🤦‍♂️

Мораль этой басни - очень важно видеть как тест превращается из красного в зелёный.
Самый рациональный и надёжный способ это делать - писать сначала тесты.
Если вы пишите сначала продовый код - надо хотя бы ломать его после тестов, и убеждаться что они красные, а потом становятся зелёными.
Ну а если вы написали продовый код, написали тесты, они сразу прошли и вы на этом остановились - ну чтож, удачи в проде:)

#case@ergonomic_code #ergo_testing@ergonomic_code #tdd@ergonomic_code
👍5
Привет!

Сегодня у меня день релизов!:)

Во-первых, я накатал обещанный микропрост про упражнения со Spring Boot Native.

А во-вторых и в главных - опубликовал первый том ретро реинжиниринга Проекта Э!

Ну и заодно немного обновил лендинг ЭП и добавил туда кейс Проекта Э

#case@ergonomic_code #project_e@ergonomic_code #posts@ergonomic_code
👍6
Привет!

Джуг наконец-то опубликовал запись моего доклада о декомпозиции на базе эффектов с JPoint!:)

А ещё они мне подарили бесплатный оффлайн билет на Джокер:) Не знаю, сколько ещё продлится этот аукцион невиданной щедрости, но приятно.

В общем ещё раз рекомендую Джуг в качестве организатора конференций - теперь я ещё в чуть большем восторге:)

#talks@ergonomic_code #ergo_approach@ergonomic_code #effects_diagram@ergonomic_code #project_camp@ergonomic_code #case@ergonomic_code
👍13🔥2🎉1🐳1
Привет!

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

Пишите тесты - они помогут найти баги в местах, где, казалось бы, только имбицил может баг допустить.

#tdd@ergo_approach #case@ergo_approach
💯11
Карта канала

Добро пожаловать на канал "Эргономичный код" — канал о разработке поддерживаемых кодовых баз в общем и моём подходе к этой задаче — Эргономичном подходе.

Что такое Эргономичный подход?
По большому счёту это небольшой набор принципов, взятых в основном из классической школы TDD, функциональной архитектуры и DDD, и большой набор рецептов — моделей, методик и шаблонов —, которые позволяют команде быстро создавать кодовые базы, соответствующие этим принципам и, как следствие, лёгкие в поддержке.
Подробности на сайте Эргономичного подхода

В Эргономичном подходе есть что-то уникальное?
Да. Идея представления системы как модели её эффектов в виде диаграммы эффектов и методика проектирования на базе этой модели.

"Слова дёшевы, покажи мне код!"
Trainer Advisor — некоммерческий, но реальный (~17K строк Котлин кода, 15 таблиц, 2 настоящих пользователя, горки костылей, "компромиссных решений" и исторических наслоений) проект с открытым исходным кодом, разрабатываемый по Эргономичному подходу. В этот проект можно поконтрибьютить и на своём опыте прочувствовать работу с эргономичной кодовой базой.

Project Mariotte — минимальный демонстрационный пример кодовой базы, написанной по Эргономичному подходу, на примере операции бронирования номера в отеле

Есть что посмотреть или послушать?
Да, все мои публичные выступления собраны на одной странице

А почитать, кроме канала?
Да, в блоге

В блоге и канале есть подборки:
- Кейсы (в блоге, в канале #case@ergonomic_code)
- Примеры кода (в блоге)
- Эргономичный подход (в блоге, в канале #ergo_approach@ergonomic_code)
- Эргономичное тестирование (в блоге, в канале #ergo_testing@ergonomic_code)
- Функциональная архитектура (в блоге, в канале #functional_architecture@ergonomic_code)
- Эргономиный персистанс (в блоге, в канале #ergo_persistance@ergonomic_code)
- Что ещё почитать (в блоге, в канале #books@ergonomic_code, #posts@ergonomic_code, #papers@ergonomic_code)
- Что ещё посмотреть (в блоге, в канале #talks@ergonomic_code)

А у меня вопрос!
Приходите в группу - там целому сообществу (более 100 крутых инженеров) можно задать любой вопрос по тематике канала - Эргономичный подход, классическая школа ТДД, ФА, ФП, в целом дизайн модели и системный дизайн
🔥64👍3
Привет!

Продолжаю ретроспективить #project_r@ergonomic_code.

Подбил Джиру, собрал немного статистики:
1. всего задач по проекту: 223 - сюда входят и задачи на разработку, и баги, и мусорные задачи и метазадачи
2. задач на разработку по бэку проекта Р: 65
3. багов в бэке проекта Р: 12
4. регрессий в бэке проекта Р: 4
5. всего задач на разработку по бэку основного сервиса: 23
6. всего багов в беке основного сервиса: 28
7. всего регрессий в беке основного сервиса: 3
8. моих задач на разработку по бэку основного проекта: 6
9. моих багов в бэке основного проекта: 5
10. моих регрессий в бэке основного проекта: 2

Это упражнение я проделал для того чтобы проверить тезис "Применение ЭП снижает количество ошибок" и я получил очередное свидетельство этому:
1. отношение задач к ошибкам в сервисе по ЭП: 16/65 = 0.25
2. отношение задач к ошибкам в сервисе не по ЭП: 31/23 = 1.35
3. отношение моих задач к ошибкам в сервисе не по ЭП: 7/6 = 1.17

Тут по цифрам вообще выходит, что багов в 4-5 раз меньше, но, имхо, стоит сделать скидку на мою предвзятость в анализе и не учтённые факторы и сделать более консервативный вывод, что ЭП снижает количество ошибок в 2-3 раза.

Вопрос в том, стоит ли оно того - как показал опрос, большинство разработчиков не видит проблем в ошибках.

По хорошему, чтобы ответить на него, надо как-то привязаться к срокам и деньгам, но в этом проекте сделать этого не получится:
1. наверное, стоит начать с того, что по срокам мы тотально зафейлились🥲 Но по моему мнению, любой другой подход дал бы тот же результат
2. у меня есть данные только по своим трудозатратам, а в проекте участвовали ещё два разработчика
3. нет референса, к которому можно было бы привязаться.

#retro@ergonomic_code #project_r@ergonomic_code #case@ergonomic_code
🔥5👍4