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

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

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

Пара ссылок, где анкл Боб рассказывает про ООП на чисто функциональном языке (Clojure).

https://blog.cleancoder.com/uncle-bob/2023/01/18/functional-classes.html
https://blog.cleancoder.com/uncle-bob/2023/01/19/functional-classes-clojure.html

Советую почитать, даже если вы не интересуетесь ФП. Но интересоваться хотя бы ООП - надо:)

А после прочтения этих статей я наткнулся на ещё более огненный пост - https://habr.com/ru/companies/domclick/articles/732876/
Который так же упоминает посты анкл Боба.

Совпадение? Не думаю 🤯🤔

#posts@ergonomic_code #clojure@ergonomic_code #oop@ergonomic_code
🔥5
Спамить так спамить.

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

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

Как в будущем избежать таких факапов я знаю, но решил что он является хорошим поводом синхронизироваться с реальностью:)

Соответственно опрос: какой режим публикаций вам был бы более комфортен?
1. Более-менее регулярно по вторникам и пятницам
2. По мере поступления. От нескольких постов в день, до нескольких недель тишины.

Сейчас запилю собственно опрос
👍2
Какой режим публикаций вам более комфортен
Anonymous Poll
28%
Регулярный (вторник, пятница)
72%
Хаотичный
Привет!

Шутник в маинтейнерах Spring Data JDBC детектед:)
😁14
Привет!

Вчера в Проекте Э пришлось подравить пару МРов своими собственными руками (редкое событие в последнее время, к сожалению), чтобы успеть заталкать в релиз.

И в обоих случаях ТДД спасло меня от внесения багов.

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

Во втором случае, я в оригинальном МРе убрал часть логики (обновление времени действия пользователя в одном из кейсов). А потом выяснилось что всё-таки обновлять время надо. На этот кейс теста не было, поэтому я опять же начал с него. Вернул оригинальный код и. Тест не прошёл. Там был баг. Который я благополучно починил.

В общем прям советую взять в практику разработку через тесты. А чтобы это не было мучитльно больно - писать тесты без моков и на максимально высоком уровне абстракции (с позиции пользователя)

#project_e@ergonomic_code #tdd@ergonomic_code #ergo_testing@ergonomic_code
👍4🤔1
Привет!

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

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