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

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

https://azhidkov.pro
Download Telegram
Привет!

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

У нас тут в Проекте Э был аццкий баг на андроиде. Который заключался в том, что приложение случайным образом переставало подключаться к девайсу по блютузу. Угробили на него кучу времени, сил, денег, нервов, подключились всех кого можно включая меня. В результате фикс получился в 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
Эргономичный код
Привет! Кажется у меня по мотивам Проекта Э на горизонте замаячил очередной кризис Эргономичного подхода. При том зашатались одновременно два столпа - декомпозиция на базе эффектов и функциональная архитектура. С декомпозицией на базе эффектов в одном из…
Привет!

Начал таки читать OOSE - исчерпывающего ответа пока не нашёл, но пару примечательных штук заметил.

Штука №1
На 136 странице наткнулся на такой параграф:
> Thus the actual problem here was that too much specific functionality had been incorporated in the blocks (entity object in OOSE). Instead we should model this specific functionality in the control object so that, firstly the (operations of the) entity object will be more reusable in several different use cases, and secondly the specific functionality should be local and not distributed so that it is easier to introduce changes in this functionality

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

Штука №2
В книге нашёл картинку (см скрин), которая для меня полностью аналогична той картинке, с которой я начал работу над ЭП в далёком феврале 20-ого года. И на тот момент книгу я ещё не прочитал:)

#books@ergonomic_code #ergo_approach@ergonomic_code
👍3
Привет!

Крутая возможность посмотреть как на практике работают идеи, которые я продвигаю в ЭП, а Макс - в кукбуке.
Я, к сожалению, в обозримом будущем не буду набирать людей

Было бы мне актуально - сам бы пошёл к Максу:)
Forwarded from codemonsters.log (Maxim Morev)
Ищу в команду Цифровой Рубль ТехЛида
Пишите в личку @maxology

отправляйте репост своим друзьям.
50% процессы, люди
50% код, дизайн системы
Гибрид | Удаленка | Офис
💩4👍1👎1🤡1
Привет!

В Проекте Э, мы интегрируемся с внешней системой, отправляя туда часть записей дневника пользователя по протоколу MQTT.
И коллеги попросили делать это ровно один раз.
Что невозможно в нашей вселенной.

Я написал для них обоснование невозможности выполнить их просьбу и решил это оформить в микропост в блог - может быть и вам пригодится.

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

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

Прошёл Spring IO 23
И там дикая пачка любопытных по названию докладов:
- Spring is bootiful but so is your domain
- Tactical Domain-Driven Design with Spring Boot [Workshop]
- Anatomy of a Spring Boot App with Clean Architecture
- Things I Wish I Knew When I Started Testing Spring Boot Applications
- Rapid server-side full stack web development with ViewComponents and htmx
- The Aggregate is dead. Long live the Aggregate!
- Preparing web applications for Loom
- Server-side rendering (SSR) with Spring [BoF]
- Integration Testing for everyone with Testcontainers [Workshop]
- Architecturally evident Spring applications with jMolecules
- Spring Boot 3 is here: Where are you? [Workshop]
- Avoid the Distributed Monolith - Moving Towards Mature Scalable Microservice Applications with Spring
- Bootiful Spring Boot 3
- Do you really need Hibernate?
- REST next level : Crafting domain-driven web APIs
- Automating away bugs with Error Prone in practice
- Why you don't need to worry about scaling your Spring webapp

Доступны пока только 16 штук, но если не упарываться - как раз что-то ещё появится, пока то что есть посмотришь
👍5
Привет!

Листаю Designing object-oriented software и наткнулся на такой же тест как и у меня тест на разумность декомпозиции:)

За одно ещё раз попиарю - https://archive.org. Там после бесплатной регистрации можно легально откопать редкие и интересные книги:)

Единственное не удобство - читать только на сайте и раз в час надо заново "занимать" книгу.

#books@ergonomic_code #oop@ergonomic_code
Привет!

Посмотрел Keynote SpringIO 23, резюме:
1) Вышел Spring Boot 3.1
1.1) Автоматический запуск докер-композа (!) О_О - теперь реально можно запускать проекты буквально в один клик после клона репоза
1.2) Я думаю в ближайшее время переедем на него - расскажу о впечатлениях

2) Поддержка Project CRaC в Spring Framework 6.1 (осень 23) - сохранение снапошота памяти запущенного приложения при сборке, чтобы потом в проде запустить его за пару сотен миллисекунд

3) В обеих демках мелькала Spring Data JDBC (а не JPA) - у меня всё больше складывается ощущение, что Спринг пушит JDBC в качестве замены JPA

#talks@ergonomic_code #spring@ergonomic_code #spring_data_jdbc@ergonomic_code
👍2
Привет!

Кто-нибудь знает простую plain text-овую нотацию для описания HTTP API? Что-нибудь в таком духе, но ещё более Markdown-нистое.

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

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

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

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

Как и обещал, пишу о впечатлениях от переезда на Spring Boot 3.1.
Их нет.

Накрутил версию гредлового плагина до 3.1.0, заменил зависимость тестконтейнеров на testImplementation("org.springframework.boot:spring-boot-testcontainers") и всё. Приложение собралось и запустилось, все тесты прошли. Я это в мастер в следующий цикл вмёржу - может на стендах что-то вылезет.

Чуть поинтереснее история с интеграцией с композом.

1. Добавил в грэдл developmentOnly("org.springframework.boot:spring-boot-docker-compose")
2. Добавил конфиг application-local-dev.yml:
spring:
docker:
compose:
file: ./env/docker-compose-infra.yml
enabled: true
lifecycle-management: start_only

И почти всё. Была одна проблема - в какой-то обвязке кролика vhost захардкожен в "/", а нам в наследство достался нестандартный. Это подправил - и всё взлетело.

Потом ещё небольшая мелочушка была - через спринг нельзя прописать имя композ-проекта - добавил его в композ файл.

И вот это совсем всё. Теперь у нас сетап выглядит так:
1. Поставить Джаву, Идею, Докер, Гит
2. Качнуть репоз
3. Запустить приложение в Идеи
4. Готово

Я хоть и не люблю спринг за его монструозность и автомагичность, но вот такие плюшки прям подкупают.

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

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

#tools@ergonomic_code #spring@ergonomic_code #devx@ergonomic_code #project_e@ergonomic_code
👍2
Привет!

Посмотрел Don’t Build a Distributed Monolith - там мужик в бонусной проблеме как и я говорит, что микросервисы разрабатываемые одним человеком - мощная заявка на распределённый монолит.

В целом в докладе не то чтобы есть какие откровения, но посмотреть можно.

А потом посмотрел Top 5 techniques for building the worst microservice system ever. Вот тут в конце уже было некоторое откровение. Для реализации агрегации данных из разных сервисов, чувак предлагает сбор этих данных делать в репозе сервисов-владельцев, но деплоить этот код в сервисе-агрегаторе.
Я не то чтобы побежал это делать, но идея кажется любопытной.

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

#talks@ergonomic_code #why_no_microservices@ergonomic_code
🔥5
А ещё подъехали новые видосы со Spring.io 23, в том числе The Aggregate is dead. Long live the Aggregate!.

Там авторы полдоклада пинают концепцию агрегата (в целом за дело, имхо), а в конце предлагают некоторый аналог compare-and-swap/optimistic locking для эвент сорсинга.

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

#talks@ergonomic_code #ddd@ergonomic_code
Привет!

Я недавно был на тренинге по ораторскому мастерству.
И там тренер сказал, что выступать боятся все. Но опытные спикеры боятся реакции аудитории "Спасибо, Кэп". Другая большая проблема опытных спикеров - сохранять огонь в глазах.

И у меня была ровно такая реакция на последний доклад Кевлина Хенни, который я смотрел.

Поэтому когда я собирался смотреть Refactoring Is Not Just Clickbait - Kevlin Henney - NDC London 2023, я подумал, что если и там будет "спасибо, кэп" - я перестану следить за творчеством Кевлина.

И там был повтор. Но один:)

А в целом - прикольный философский доклад.

Больше всего меня там зацепило, что он попинал OCP:
> OCP - is'a a failure of good practice.It's failure of architecture, if you doing that

Но он (как и анкл Боб, впрочем) лукавит. Думаю намеренно.
Потому что ответ на вопрос "Хорош ли OCP", как всегда - It Depends.
Если вы делаете прикладное приложение и боитесь его менять - это действительно проблема архитектуры.
А вот если вы делаете фреймворк, или платформу со сторонними плагинами - без OCP ничего не получится.
Вопрос в том, много ли из нас делает фреймворки и платформы:) Запилю-ка опрос:)

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

#talks@ergonomic_code
Привет!

С подачи Романа Русакова запоем прочитал The API.
Очень крутая книга, рекомендую.
Роман - спасибо:)

Так же вы, возможно, задаётесь вопросом что это я затих.
Вряд ли, конечно, но я всё равно отвечу - лопачу джиру Проект Э:)
Чтобы понять стоило ли оно того. Джира, у нас, к сожалению, не в лучшем состоянии и я не большой специалист по её анализу, поэтому идёт тяжко и в зависимости от методики результат получается от хрен на хрен, до 10х улучшения. Но что радует - нигде нет просадки ни по одной метрике.

Сейчас я вроде собрал методику, которая должна дать более-менее вменяемые цифры, которые, я надеюсь сойдутся к 1.5х снижению трудозатрат и 2х снижению кол-ва багов.
Осталось доразмечать 517 задач:)

#books@ergonomic_code #http_api@ergonomic_code
👍3🥰1
Привет!

Микроретро со статистикой по реинжинирингу уже почти готово - завтра-послезавтра опубликую. Спойлер - могу с уверенностью заявить, что цели "сократить трудозатраты и количество багов вдвое" нам удалось достичь:)

И сейчас я пишу спекулятивную часть - "А чтобы было, если бы реинжиниринг выполнялся по мейнстримному подходу - с тестами на моках, Hibernate и пакетированием по техническим аспектам?"

Написав это, я засомневался - а правда ли это всё ещё мейнстрим? А то вон на конференциях всё чаще мелькает Spring Data Jdbc, всевозможные вариации на предмет вертикальной декомпозиции и ДДД.

Решил проверить так - взять первую попавшуюся на Packtpub-е свежую книгу по спрингу и посмотреть что там. И знаете что там? Ровно всё то, что я перечислил:)

На всякий случай глянул вторую книгу - там пакетирования вообще никакого нет, зато хибер и моки - на месте:)

Обе книги - декабрь 22-ого года.
Привет!

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

И так, та-да-да, микропост с результатами анализа 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