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

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

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

Недавно посмотрел доклад с последнего JPoint-а, который продвигает подход, процентов на 80 совпадающий с Эргономичным.

По традиции, в этом докладе не было ничего о декомпозиции систем.
Но самое важное - в докладе продвигается традиционный подход к Railway-Oriented Programming на монадах.

Я пробовал так делать, мне не понравилось и сейчас я переключился на "пролетарский ROP на охранных выражениях".

И чтобы предостеречь вас от повторения моих ошибок и применения монадического ROP-а там, где о не нужен, я накатал микропост с обзорным сравнением монадического и пролетарского РОПа.

#posts@ergonomic_code #talks@ergonomic_code
👍3
image_2022-11-19_14-21-52.png
439.5 KB
Привет!

Тизер моей текущей активности.

Года два-три назад я как-то рассказывал коллеге насколько плохО пакетирование по слоям. В ответ он задал мне невинный вопрос без задней мысли - "А как по другому"?
И тут я сдулся - вменяемого ответа на тот момент у меня не было.

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

И самую сложную часть этого ответа - как декомпозировать ядро системы на подсистемы - я сделал. Во-первых это Диаграмма Эффектов, а во-вторых это методика декомпозиции на её базе (расписанная пока что верхне-уровнево). Для того чтобы зафиналить эту часть и закрыть гештальт, осталось буквально три чисто технических шага - подробно расписать методику декомпозиции, привести пример декомпозции ДЭ проекта TSP, привести пример перевода ДЭ и модулей в код. Однако я отвлёкся.

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

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

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

И напоследок: ещё один любопытный подход к декомпозиции систем

#ergo_approach@ergonomic_code #project_e@ergonomic_code #guideline@ergonomic_code #posts@ergonomic_code #clojure@ergonomic_code
🔥3
image_2022-11-30_12-44-40.png
202.6 KB
Привет!

Я в целом собрал свою версию структуры модуля. Она всё так же похожа на структуру из Let's build components, not layers и базируется на интерфейсе и реализации. Но я решил отдельно вынести порты - штуки, которые публикуют АПИ модуля наружу и "конфиг" - спринговый конфиг, который позволяет создать экземпляр модуля в рантайме.

У меня получился такой список типовых (под)пакетов модуля:
- api
- dtos - классы DTO АПИ модуля
- events - классы событий модуля
- model - классы сущностей и объектов-значений из DDD, в случае если они "выставлены" в АПИ
- *Exception - файл с иерархией исключений модуля
- *Service - файл с интерфейсом модуля
- internal
- db - классы репозитория и сущностей модуля и, при наличии, DAO и строки
- submodule1 - подпакет с кодом реализации подмодуля
- Submodule2.kt - котлин-файл кодом реализации подмодуля
- *ServiceImpl - файл с классом реализации интерфейса модуля
- *Props - класс конфигурационных параметров модуля
- ports
- *Controller - Spring MVC контроллер и обработчик ошибок
- *Listener - Spring RabbitMQ слушателя
- *Config - Spring-конфигурация модуля

Я перепаковал так Проект Э, TSP Project и ещё один нетиповой проект - пока полёт нормальный. Дальше хочу ещё перепаковать Кэмп, Проект Л и ещё один коммерческий проект (у каждого из них есть уникальные особенности) и после этого пойти писать вторую версию поста "Структура эргономичной кодовой базы" (осторожно, материал этого поста частично устарел).

#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #project_e@ergonomic_code #project_camp@ergonomic_code #project_geoservices@ergonomic_code
👍3🌚1
Привет!

Я уже писал, что даже декомпозиция на базе эффектов не является уникальной для ЭП.

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

Identifying Microservices Using Functional Decomposition

Сам эту статью ещё не читал, горячим пирожком поделился:)

#papers@ergonomic_code #effects_diagram@ergonomic_code #ergo_approach@ergonomic_code
👍2
Привет!

Я прочитал Identifying Microservices Using Functional Decomposition - вы можете не читать, там ни чего особо нового:)
Самый полезный бит информации, это то что авторы экспериментально на трёх реализациях одного проекта подтвердили мой тезис "Она [декомпозиция на базе эффектов] проще в изучении и применении группировок по фичам, компонентам и ограниченным контекстам/агрегатам, но даёт результаты такого же качества." [1].
У них получилось, что интуитивная декомпозиция требует "дней", а автоматизированная на базе эффектов - "часов". А результаты идентичные

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

#effects_diagram@ergonomic_code #ergo_approach@ergonomic_code
👍2
Молния!

Я, возможно, тормоз, но я тут открыл github codespaces

И они реально работают - мне тут надо было подправить пулл реквест в спеку диаграммы эффектов, я открыл ветку в спейсе, мне открылся ВС Код, я там поставил плагин аскиидока, и открыл превью! О_О
Поставил вим и он заработал
А вот синк сеттинги на веб не поставились.
Но в любом случае, это вполне рабочий вариант что-то подхачить в приличной среде, не выходя из облака

#tools@ergonomic_code
Привет!

Вчера задеплоили в прод результаты первых трёх спринтов -первый кусочек (~20%) нового бэка Проекта Э, в проде нашли один баг нового бэка, и старый баг в старом бэке:) Я считаю неплохо.

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

Касательно Эргономичного подхода у меня на подходе (pun intended) лендинг для него - планирую зарелизать на следующей недели

А до конца года я собираюсь выложить версию 0.1.0 диаграммы эффектов, с более согласованной концептуальной моделью и остальной частью отредактированной профессиональным техписателем.

После этого я наконец вернусь к большим постам. Сейчас у меня есть идеи четырёх потенциальный поста:
1) Наконец написать пост по декомпозиции проекта TSP на базе диаграммы эффектов
2) Пост о шаблоне раскладки кода по пакетам в Эргономичном подходе
3) Пост о том, почему я считаю, что ФП стиль даёт лучшие результаты, с точки зрения суммарной стоимости разработки
4) Собственный пост о функциональной архитектуре с заходом через трансформационно-центричную морфологию из структурного дизайна.

Так же практика прошлых лет показывает, что у меня первая половина года намного богаче на посты, чем вторая, так что стей тюнед, будет интересно:)

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

Зарелизил анонсированный на прошлой недели лендинг Эргономичного подхода:)

Теперь вам есть куда отправить уставших от багов и вечных спринтов разработчиков и владельцев продуктов:)

Пользуясь случаем, хочу ещё раз выразить благодарность руководителям проектов, на которых я обкатывал ранние версии ЭП: Николаю Макарову, Денису Исаеву, Евгению Тимофееву и Дмитрию Семёнову - парни, без вас бы ЭП не было.

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

Написал очередной микропост на тему того, "Почему ФП?".

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

А вот и подошла очередь анонсированного ранее релиза спеки диаграммы эффектов в0.1.0.

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

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

#posts@ergonomic_code #effects_diagram@ergonomic_code #ergo_approach@ergonomic_code
👍4
Привет!

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

> You may have heard of famous Classicist TDD practitioners including Uncle Bob and Kent Beck. If you want an example of a Mockist look no further than Sandi Metz, J.B Rainsberger or Steve Freeman
Test Driven Development Wars: Detroit vs London, Classicist vs Mockist

Так, ну анкл Боба и Бека каждая собака знает. Если что, Фаулер - тоже классицист.

А вот за эти ваши моки - что за господа (и дамы) с горы топят? Они даже в выдаче стартпейджа ниже футболистов. Единственное известное (мне) творение этих авторов - Growing Object-Oriented Software, Guided by Tests - Хориков (тоже классицист) в части дизайна и качества тестов разнёс в пух и прах.

А если серьёзно, я начинаю потихоньку отходить от абсолюта "не используйте моки никогда!" - так что не сильно удивляйтесь, увидев пост "Когда и как стоит использовать моки?":) Тизер: тогда, когда надо симулировать ошибку, отгородится от дорогой/медленной/нестабильной внешней системы и стараться мокать только стабильные интерфейсы.

#posts@ergonomic_code #ergo_testing@ergonomic_code #tdd@ergonomic_code #whynomock@ergonomic_code
Привет!

У меня появилась странная идея. Написать пост "Зачем декомпозировать систему?". Кажется, идея провалится, потому что ответ пока что сводится к "затем", но эта деятельность натолкнула меня на хорошую мысль.

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

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

Зато есть несколько вещей, в которых я уверен:
0. кодовая база должна иметь регулярную структуру, для того чтобы в ней было проще ориентироваться
1. декомпозиция второго уровня неизбежно будет дублироваться - внутри каждого модуля первого уровня надо будет поддерживать декомпозицию второго уровня, такую же, как и в соседних. Из-за этого декомпозицию второго уровня поддерживать сложнее, чем первого
2. техническая декомпозиция уже устоялась и практически не меняется. В разных командах могут быть небольшие отличия, но множества ключевых слоёв и типов классов имеют конечный размер. Благодаря этому техническую декомпозицию поддерживать просто.
3. декомпозиция предметной области (для всех проектов) не может быть устоявшейся, т.к. количество предметных областей условно бесконечно. Из-за этого:
3.1. каждой команде надо заново придумывать свою декомпозицию предметной области
3.2. декомпозиция может эволюционировать вместе с пониманием командой предметной области или даже самой предметной областью
3.3. поддерживать декомпозицию предметной области сложно - её нельзя заучить один раз на всю карьеру, она меняется даже в течении жизни одного проекта и в целом она может быть намного сложнее, чем 3 слоя и десяток типов классов

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

Ну а декомпозировать систему в принципе надо потому что потому. Я серьёзно. В литературе так и пишут
Например, в статье о структурном дизайне пишут, что мистер Константин "наблёл", что проще реализовывать и изменять те программы, что состоят из простых независимых модулей.
> Mr. Constantine has observed that programs that were the easiest to implement and change were those composed of simple, independent modules

Никакими фактическими данными по объективным метрикам наблюдения мистера Константина не подкрепляются.

Наконец, пришёл я ко всей этой цепочке в процессе [мысленной] дискуссии с Фаулером по мотивам его статьи о сцепленности, где он на первый (и единственный) уровень вытащил техническую декомпозицию и на которую я натолкнулся как раз в процессе поиска ответа на вопрос "зачем декомпозировать системы"

#ergo_approach@ergonomic_code #ergo_arch@ergonomic_code #papers@ergonomic_code
👍6
Привет!

Проснулись? Похмелились?:) Вот вам линко пост потупить в кровати, пока раскачиваетесь:) С прошедшим:)

Подвернулась под руку хорошая статья по дизайну REST API. Там никаких откровений, но в одном месте и кратко собрана вся ключевая информация о том, как проектировать хорошие API.

#posts@ergonomic_code #http_api@ergonomic_code
🔥5
Привет!

Чем задро люди, нашедшие работу по душе занимаются на праздничных днях? Правильно - переводят проекты на 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
Привет!

Посмотрел доклад "Меняем Spring Data JPA на Spring Data JDBC!". Хотя докладчик в начале сказал, что не призывает использовать JPA, мне что-то захотелось написать микропост в защиту Spring Data JDBC.

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

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

Сейчас делаю второй подход к посту декомпозиции, откопал его, перечитал, снова впечатлился и на это раз решил поделиться с вами:)

#posts@ergonomic_code #coupling@ergonomic_code #cohesion@ergonomic_code
Привет!

Пост про ОО-декомпозицию начинает обретать вменяемый вид - надеюсь в течении пары недель закончить:)

А тем временем, буду радовать вас линкопостами:)
Вот очень крутой конспект/лекция (?) из MIT-а про изменяемость/неизменяемость, с хорошими примерами рисков, которые несёт изменяемость. Если вы по дефолту используете изменяемое состояние - рекомендую прочитать, может быть передумаете:)

А если вы используете неизменяемое состояние и Котлин - то вот небольшая библиотека для упрощения жизни. Сам ещё не пробовал её

#posts@ergonomic_code #whyfp@ergonomic_code #immutable_domain_model@ergonomic_code
👍2
Привет!

В продолжение темы неизменяемых данных: Почему Java делает так много штук неизменяемым?
ТЛ/ДР - потому что неизменяемые штуки потоко-безопасны и благодаря постоянным улучшениям JVM создание нового объекта зачастую может быть быстрее мутации старого

#posts@ergonomic_code #immutable_domain_model@ergonomic_code #java@ergonomic_code
👍3
Привет!

Что-то я прокрастинирую пост о декомпозиции. Самое мясо с декомпозицией написал, а вот полировка буксует - то пойду писать спинофф про эффекты, то доделывать спинофф "почему всё-таки объектно-ориентированная?", то пинать Spring Data Jdbc, то болеть.

Но я его точно допишу.

А пока вот ещё одна любопытная линка - альтернативное массиву предстваление строк.

#posts@ergonomic_code
👍2