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

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

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

Я не умер. И канал не умер. И я не забил ни на канал, ни на ЭП:)

Последнее время я активно допиливал Trainer Advisor. И теперь TA содержит всю базовую функциональность.

В цифрах это:
1) 14 таблиц
2) 12 страниц UI
3) 57 эндпоинтов
4) 4378 строк продового Kotlin-кода
5) 136 интеграционных + 2 мок-теста + 2 юнит теста + 1 архитектурный тест = 141 тестов, проходящих за 17 секунд
6) 1e2e Селениум тест

Это всё написано более-менее по текущим канонам ЭП и публично доступно для изучения и ознакомления.

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



Прямо сейчас в коде ТА хорошо проиллюстрированы две части ЭП:
1) Неизменяемая модель данных
2) Подход к тестированию

Так же с помощью 370 строк кода мне удалось решить две самые большие боли Spring Data JDBC:
1) Динамические критерии выборки
2) Подгрузку ссылочных данных для вывода на фронт (без дублирования структуры доменных объектов)

И сейчас решение этих задач у меня выглядит так:

// Выборка по динамическим параметрам:
findAll(pageRequest) {
Client::therapistId isEqual therapistId
Client::firstName isILikeIfNotNull clientSearchDto.firstName
Client::lastName isILikeIfNotNull clientSearchDto.lastName
Client::phoneNumber isILikeIfNotNull clientSearchDto.phoneNumber
}
// Выборка с подгрузкой ссылок
object Appointment.Fetch {
val summaryRefs = listOf(Appointment::clientRef, Appointment::typeRef)
val editableRefs = summaryRefs + Appointment::therapeuticTaskRef
}
val appointment = appointmentsRepo.findById(appointmentId, Appointment.Fetch.editableRefs)


Естественно, их можно комбинировать, но пока в проекте такой потребности нет.

Но эта работа так же помогла мне проявить пару противоречий и нерешённых проблем в ЭП:
1) С ФА есть проблема в том, что в большинстве моих проектов бизнес-логики (чистого ядра) набирается от силы процентов 10, а всё остальное - линейный круд. И кажется что это противоречит тому что ФА является одним из столпов ЭП
2) Реальный мир не всегда хорошо ложится на плоскую картину use case/workflow даже 3ей версии эргономичной структуры программ.

Что с этим делать - пока не знаю



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

#trainer_advisor@ergonomic_code #ergo_approach@ergonomic_code #ergo_persistance@ergonomic_code
🔥13👍42🤯1
Привет!

Я похоже опять всё прослоупочил и в мире уже во всю обсуждают Data-Oriented Programming, в качестве (зачастую) более вменяемой альтернативы ООП - то, что я называл "пролетарским ФП" - программирование на чистых функциях, с неизменяемыми структурами данных и алгебраическими типами данных (и без монад и остального ада высшего порядка).

Гетц (ведущий дизайнер Java) пишет лонгриды про DOP в Java
Кложуристы пишут книги про DOP с примерами на JavaScript
Какой-то чувак на какой-то конфе рассказывает про DOP на Kotlin

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

И в целом, я сейчас подумываю о существенной переработке ЭП и переходу от трёх столпов, к рекомендациям по четырём разделам:

1) Дизйн данных: неизменяемые реляционные данные - изменяемые списки неизменяемых деревьев объектов со ссылками между ними по ИДам (читай - репозитории агрегатов)
2) Дизайн операций: модернизированный структурный дизайн - рекурсивное разделение кода на координатора, ввод/вывод (процедуры) и трансформации (чистые функции) - и всё это с высоким cohesion
3) Группировка кода: дальнейшее развитие эргономичноый струкутры программ в3 слои приложения (операций, поведения) и домена (данных, состояния, внешних систем).
- Приложение делится по ролям, внутри ролей по экранам UI или Юз кейсам
- Домен делится на поддомены на основе аналитики (или UI, или на глаз), поддомены делятся компоненты по обновлённому алгоритму декомопзиции на базе эффетов
4) Автоматизация тестирования: практически без изменений - минимум моков (только для тестирования ошибок и подмены дорогих внешних систем), взаимодействие через публичное АПИ, тестирование системы на соответствие требованиям.

#ergo_approach@ergonomic_code #dop@ergonomic_code
5🙏3❤‍🔥2
Привет!

Я уже давно не читаю переводов технических книг.

Думал, что переводы бизнес-книг можно читать, и "Как создать продукт, который купят. Метод Lean Customer Development" начал читать на русском.

Там есть русский текст:
> Не считая поиска собеседников, подготовки вопросов и работы с заметками, а также обобщения полученной информации, на это уйдет примерно две недели. И если вы увидите, что можно отказаться хотя бы от одной из этих задач, вашу работу по развитию потребителей уже можно считать оправданной.

А оригинал:
> Between recruiting participants, preparing questions, taking notes, and summarizing, that equates to about two weeks of work. That may sound like a lot of effort, but if you learn that you can cut a single feature, you’ve already justified the investment in customer development

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

Хоть перечитывай оригинал с начала.

Не читайте переводов книг, если авторы не русскоговорящие (например, принципы юнит-тестирования) - совершенно непонятно что у них общего с оригиналом.
Единственное известное мне исключение - scip

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

Я несколько лет назад придумал тезис: у бизнеса и разработчиков одна цель - быстро выпускать фичи без багов.

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

- Я (пока что скорее голословно) утверждаю, что ЭП позволяет быстро выпускать фичи с минимумом багов

- Если удастся собрать данные, которые подтверждают п. 1 для бизнеса - это создаст общую терминологию для коммуникации разработчиков с бизнесом.

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

Осталось сделать самую "малость" - провести двойные слепые рандомизированные исследования об эффективности работы по ЭП и... неЭП

#posts@ergonomic_code
👍2
И заодно -- как вы относитесь к явной рекламе?

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

Сейчас сделаю опрос
👍2
Как вы относитесь к явной рекламе?
Anonymous Poll
83%
Нейтрально
15%
Отрицательно
2%
Другое (напишу комментарий)
👍2
Привет!

Если долгими томными вечерами вы как и я любите позаниматься странным - например, почитать древние научные статьи на английском - то рекомендую почитать статью VALUES AND OBJECTS IN PROGRAMMING LANGUAGES, которая рассматривает с математически-философской точки зрению разницу между объектами и данными (ака сущностями и объектами-значениями).

ТЛДР - объекты изменяемые, а данные - нет; и в реальной жизни надо и то и то.

Ещё пара хлёстких цитат оттуда:
1) "Computer science - это объектно-ориентированная математика"
2) Программирование - это объектно-ориентированная математика, математика - это "value-oriented" программирование.

Эта статья подтолкнула меня поискать объекты в Trainer Advisor. И хотя конструкция object встречается 17 раз, изменяемый объект я нашёл только один - билдер динамических запросов. И то он изменяемый только потому, что Котлин (пока?) не достаточно data-oriented и не поддерживает литералы списков и мап.

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

#papers@@ergonomic_code #oop@ergonomic_code #dop@ergonomic_code
👍4
И про рекламу

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

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

В итоге я сформировал следующую позицию (с учётом того, что большинство читателей не против рекламы):
1) У меня нет и не будет цели монетизировать этот канал с помощью рекламы
2) Но я допускаю размещение рекламы для развития канала, при условии что:
2.1) Рекламируемый продукт не противоречит УК РФ и моим морально-этическим убеждениям
2.2) Реклама будет сопровождаться соответствующим дисклеймером
2.3) Я сам верю в то, что пишу

Исходя из этой позиции, я вижу два возможных вида рекламы на канале:
1) Поддержка поста - я посвящаю написанию текущего поста дополнительное время, пропорционально "рекламному бюджету" и в замен добавляю в пост ссылку на рекламодателя со словами, что пост написан при его поддержке

2) Совместный проект - сейчас в голову приходит только мой приход в гости в чей-то подкаст и соответственно ссылки друг на друга, но в целом возможны и другие варианты.
👍82
Привет!

Финализирую первый пост с описанием тестирования TA и походу дела накапал небольшую неопубликованную заметку с его архитектурой и стеком. И вот опубликовал:)

А пост с тестированием, думаю, на этой недели опубликую.

#trainer_advisor@ergonomic_code
👍4👌2
Привет!

Опубликовал первый пост про тестирование TA с общими идеями и принципами (но уже здесь с иллюстрациями реальным кодом из TA).

#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code
👍2
И тизер следующей части, где кода и картинок больше, чем текста:)
Привет!

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

Лично меня больше всего порадовала мысль Андроид разработчика, что бэк - это не деталь реализации, а домен:)

Правда следуя этой логике, можно прийти и к тому, что БД - это не деталь реализации, а домен:)
Что, на самом-то деле, похоже на правду - я уже не раз выкидывал "ядро" системы в виде кода, оставляя "деталь реализации" в виде данных в текущей схеме и строил новое ядро поверх этой детали.

#posts@ergonomic_code #clean_architecture@ergonomic_code
🔥41
Привет!

Если вы как и я в последние лет 6 несколько раз пытались дедуплцировать версии зависимостей в мультипроектном Gradle-билде на Kotlin DSL и всякий раз терпели крах: кажется, наконец-то появился вменяемый способ это сделать - в 7-ом Грэдле оказывается появилась фича каталога версий

#tools@@ergonomic_code #gradle@ergonomic_code
2
Привет!

Меня тут после 3ёх лет работы исключительно на Kotlin (+ Spring Data JDBC) занесло писать на Java 8 (+ JPA).

После Котлина - такое ощущение, как будто-то на Си пишешь - любое действие требует намного большего количества кода и на каждом шагу либо сам себе в ногу стреляешь, либо попадаешь в капкан древних.
А вот фана, от того, что у тебя процессор практически под коничиками пальцев нет...

В общем, если вы сейчас на Java (даже свежей - там всё равно нет null-safety и нормальных утилит манипуляции данными) - рекомендую попробовать Kotlin - DevX у Котлина на порядок выше.

P.S>
В комментариях пишут про другой опыт - видимо, тут как и везде на вкус и цвет:)
Но, тем не менее, если ещё не пробовали Kotlin - попробуйте - возможно наши вкусы совпадают и тогда вас ждёт чудный новый мир:)

А чтобы интереснее было пробовать - можно мне в Trainer Advisor поконтрибьютить:)

#whykotlin@ergonomic_code
2🤔1
image_2024-04-04_08-27-40.png
817.8 KB
Привет!

"Золотые слова, Юрий Венедиктович!"

Доклад: https://www.youtube.com/watch?v=9Q7GANXn02k

#talks@ergonomic_code #why_no_microservices@ergonomic_code
💯51
Привет!

Опубликовал второй кусочек описания тестирования Trainer Advisor - сетап system under test.

#trainer_advisor@ergonomic_code #ergo_testing@ergonomic_code
🔥71
Привет!

Начал читать Code That Fits in Your Head, пока прочитал только 50 страниц, но книга уже нравится.

В частности там есть очень крутой заход на важность локальности рассуждений/исключения скрытых эффектов через Систему 1 Канемана из Думай медленно… Решай быстро, который получил нобелевскую премию за исследования описанные в этой книге.

Так вот, Канеман говорит, что у нас есть два режима мышления - Система 1 и Система 2.
Система 1 - это то как мы размышляем обычно - на автомате, без затрат усилий
Система 2 - это когда мы целенаправленно прикладываем усилия для размышлений.

И так как Система 2 требует значительных энергозатрат, мы не можем постоянно работать на ней и большую часть времени работаем "спинным мозгом" - Системой 1.

А Система 1 "строит истории" только на основе того, что она видит прямо сейчас.
Соответственно, если взять видимый кусочек кода, которым я иллюстрировал проблемы побочных эффектов:
fun main() {
val els: ArrayList<Int> = arrayListOf(2, 2)
val sum = sum(els)
println("Сумма ${els[0]} + ${els[1]} = $sum")
}


То глядя на него Система 1 быстро придумает историю, что sum вернёт значение, не поменяв els и выводом программы будет "Сумма 2 + 2 = 4". А это не так.

В общем минимизируйте количество изменяемого состояния в ваших программах, чтобы истории ваших Систем 1 чаще были правдоподобными:)

#whyfp@ergonomic_code #books@ergonomic_code
2
Привет!

Узнал новый для меня термин в области архитектуры систем - Цитадель. И он явно лучше подходит для того, что я имел ввиду, когда говорил о Микроядерной архитектуре

#posts@ergonomic_code
👍41
image_2024-04-12_11-01-07.png
90.8 KB
Привет!

Я тут проснулся с мыслю - а вам не кажется, что Микросервисная, Гексагональня и Кричащая архитектуры - это всё про разное? И один проект может соответствовать всем трём сразу?
3
Привет!

Решил попробовать завести группу, посвящённую применению основных идей ЭП (модульные монолиты, неизменяемую модель данных, функциональную архитектуру, интеграционные тесты, outside in TDD, data-oriented programming) на практике.

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

Присоединяйтесь, будет полезно:)

P.S. Буду благодарен за репост:)