Warning: Undefined array key 0 in /var/www/tgoop/function.php on line 65

Warning: Trying to access array offset on null in /var/www/tgoop/function.php on line 65
456 - Telegram Web
Telegram Web
Привет!

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

В связи с чем у меня возник вопрос - а их сейчас вообще хоть кто-то рисует?
Вы используете UML class diagram в каждодневной практике для детального проектирования/описания кода?
Anonymous Poll
4%
Да
93%
Нет
4%
Свой вариант
Привет!

Не прошло и месяца и я сделал это!

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

У меня есть идея ещё пары-тройки проектов, с демонстрацией более развесистой бизнес-логики и более сложными взаимодействиями с инфраструктурой - надеюсь на горизонте пары лет их я тоже сделаю:)

#project_mariotte@ergonomic_code #ergo_approach@ergonomic_code #spring@ergonomic_code #tdd@ergonomic_code #functional_architecture@ergonomic_code #dop@ergonomic_code #immutable_domain_model@ergonomic_code
👍16🔥6
Привет!

Я в Project Mariotte сделал страшное - перешёл на MockMvc.

Изначальная мотивация была в том, чтобы сэкономить секунду на запуске Tomcat.

Потом выяснилось, что инициализация RestAssured занимает ещё секунду, которую тоже можно сэкономить

Но последним аргументом стало то, что со WebTestClient можно переехать на работу через HTTP за три четыре простых шага.

И это навело меня на мысли об эволюции ЭП от сложного к простому за последние 4 года.

В конце 19-ого - начале 20-ого года можно было сказать, что ЭП = модульный монолит + тесты без моков + ДДД + чистая архитектура + railway-oriented programming на монадах.

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

Но за прошедшие 4 года, они все если не вошли, то сильно приблизились к мейнстриму, на мой взгляд.

А я с ЭП за эти же 4 года то ли ушёл вперёд, то ли откатился назад:

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

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

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

4. Чистую архитектуру я заменил на тщательное проектирование интерфейсов;

5. ROP на монадах, наконец, я заменил на Guard clause.

И при этом Эргономичный подход остаётся совместимым со всеми этими идеями там, где это надо:

1. Цитадель оказалась плохой затеей? Затолкать её обратно в монолит - вообще не проблема;

2. Тестов на моках стало слишком много или появилось слишком много багов в обработке ошибок? Поменять моки на стабы - уже сложнее, но тоже вполне решаемая задача;

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

4. В проекте появилась необходимость менять инфраструктуру без пересборки/перезапуска? Вытащить интерфейс из существующего класса - дело 5 минут. С реализацией сложнее, но это другой вопрос;

5. В проекте появилась потребность на лету собирать пайплайны? Обернуть имеющиеся вызовы эффективных методов в монады не составит труда.

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

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

Теперь Эргономичный подход стал глотком свежего воздуха для тех, кто устал от поисков стороны, с которой подойти к ДДД, церемоний чистой архитектуры и сложностей объяснения монад простым смертным.

В общем, покой нам только снится:)

#ergo_approach@ergonomic_code #project_mariotte@ergonomic_code #tdd@ergonomic_code #ergo_testing@ergonomic_code #mocks@ergonomic_code #clean_architecture@ergonomic_code #functional_architecture@ergonomic_code #ddd@ergonomic_code #rop@ergonomic_code
👌2
Эргономичный код
Привет! Я в Project Mariotte сделал страшное - перешёл на MockMvc. Изначальная мотивация была в том, чтобы сэкономить секунду на запуске Tomcat. Потом выяснилось, что инициализация RestAssured занимает ещё секунду, которую тоже можно сэкономить Но последним…
После Project Mariotte я перенёс подход с MockMVC на другой (закрытый) проект и словил там проблему - по дефолту настройки секьюрити не подтянутся.

Для того чтобы их прикрутить надо:
1. Не забыть добавить зависимость testImplementation("org.springframework.security:spring-security-test")
2. Донастроить webTestClient:
         client = MockMvcWebTestClient
.bindToApplicationContext(applicationContext)
.apply(springSecurity(FilterChainProxy(securityFilterChain)))
.configureClient()
.defaultHeader("Content-Type", "application/json")
.build()


Возможно там где-то дальше ещё какие-то грабли есть, но меня утешает мысль, что вернуться к тестам через HTTP можно будет лёгким движением руки

#ergo_testing@ergonomic_code #tdd@ergonomic_code #mockmvc@ergonomic_code #springsecurity@ergonomic_code #webtestclient@ergonomic_code
👍4
Привет!

Я посмотрел Migrating from (Spring Data) JPA to Spring Data JDBC.
И пересмотрел Меняем Spring Data JPA на Spring Data JDBC! (на который уже писал своё фи).

Удивительно, насколько эти доклады об одном и том же разные:
1. Дженс начинает с тестов и выделяет для них целый слайд. Андрей между делом упоминает их в конце доклада
2. Дженс топит за то, чтобы делать это очень аккуратно и постепенно и рассказывает про любопытную методику больших рефакторингов. А Андрей шарашит с распахнутым забралом и даже без тестов
3. Дженс практически ~50% доклада (~20 минут из ~40) посвящает перепроектированию модели данных. Андрей посвящает этому ~3% (~2 минуты из ~60)
4. Естественно, Дженс чморит JPA, а Андей - SDJ

Зато, оба доклада раскрывают тему генерации id 🤷‍♂️ И я до сих пор не понимаю, чем default nextval('seq') плох, раз уж generated always as identity не подходит

И эта разница навела меня на новый аргумент против jpa за sdj.

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

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

И хотя, теоретически, JPA позволяет так же выполнить декомпозицию модели, она не обязывает это делать.
В результате в приложениях на JPA на декомпозицию предметной области забивают и в ответ получают Big Ball of Mud. Так произошло в 100% проектах на JPA, которые я видел.

Проектирование агрегатов - действительно сложная тема и по ней написано много хороших книг. Но с ними со всеми есть одна проблема - они полагаются на экспертов предметной области.

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

Из-за этого проектирование агрегатов зачастую хромает на обе ноги.

Поэтому я сейчас использую более технический подход к проектированию агрегатов. Об этом подходе надо написать отдельный пост, но если вкратце, он выглядит так:
1. Спроектировать ЕР модель, особое внимание уделить слабым сущностям
1.1 Признаки слабой сущности:
1.1.1 её жизненный цикл ограничен жизненным циклом другой сущности - позиция заказа не может существовать без заказа, номер не может существовать без отеля
1.1.2 она упоминается всегда в контексте другой сущности - вторая строчка заказа такого-то, номер 215 отеля такого-то
2. Все стержневые сущности (со слабыми и без них) считаются корнями агрегатов
3. Провести транзакционный анализ - в идеале в рамках одной транзакции должен меняться один агрегат и меняться целиком. Если это не так - что-то надо объединить, а что-то разделить.

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

Ещё ссылки по теме:
1. Нотация описания неизменяемой модели данных (+ Ответы на вопросы по Эргономичной нотации ER-модели)
2. Агрегаты
3. Рациональный подход к декомпозиции систем на модули или микросервисы

В общем, инвестируйте свой интеллект в решение присущей сложности задачи, а не привнесённой:)

#why_sdj@ergonomic_code #whynojpa@ergonomic_code #ddd@ergonomic_code #spring_data_jdbc@ergonomic_code #jpa@ergonomic_code
👍76
Привет!

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

Но моя карьера его опровергает.
Первые 12 лет работы в найме, мне действительно приходилось довольно много работать с чужим кодом: я поработал над 8 "зрелыми" 4 "свежими" (до 2 лет жизни) проектами. И сделал с нуля 6 проектов.

А вот после перехода в независимые консультанты соотношение кардинально поменялось: 18 новых проектов (в некоторых я был только лидом и сам код практически не писал), против 4-ёх зрелых проектов (свежих не было).

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

Ну и, конечно же, по ходу дела будет много интересных приключений, о которых я буду писать:)
Первое приключение уже есть - я нашёл способ, как в тестах поднимать с нуля чистую БД на 300+ таблиц и с 8 годами liquibase xml-миграций, так чтобы в запуск тестрана из одного теста укладывался в 4 секунды
Думаю, на недельке расскажу подробности.

В общем стей тюнед, будет ещё интереснее:)

PS> а, да, если вы в основном работаете с легаси и вам это не нравится - задавшись целью, это можно изменить:)

PPS> в дальнейшем, оригинальный проект я буду называть "Project U", а новый сервис - "Project R"

#ergo_approach@ergonomic_code #project_u@ergonomic_code #project_r@ergonomic_code
👍65
Привет!

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

На мой взгляд их можно свести к паре слайдов

#talks@ergonomic_code #whykotlin@ergonomic_code
👍6👎1
Привет!

Я как всегда облажался с оценкой оверхеда на сетап проекта и сроки по Проекту Р начали подгорать.
Поэтому на этой недели не расскажу, как поднимаю БД на 300+ таблиц, собираемых из 8 лет миграций меньше чем за пару секунд.

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

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

spring:
datasource:
url: "jdbc:tc:postgresql:16.3:///bender?TC_REUSABLE=true&TC_TMPFS=/var:rw"


#tdd@ergonomic_code #integration_tests@ergonomic_code #project_r@ergonomic_code
👍3
Привет!

Сроки по Проекту Р уже полыхают синим пламенем но я, тем не менее, повыкраивал по чуть-чуть времени на микропост с описанием того, как я добился сетапа свежей БД на 300+ таблиц за 1.5 секунды.

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

По совету подписчика начал читать Grokking Simplicity.

Пока прочитал 200 страниц из 600, но уже не могу удержать в себе восторг.

Это лучшая известная мне книга по функциональному стилю (или скорее data-oriented programming), с лучшим известным мне разбором двух основополагающих принципов проектирования:

1. разделение ввода-вывода и бизнес-логики
2. использование одного уровня абстракции в функции (анкл Бобовскя заметка на эту тему в чистом коде - даже близко не лежала с 1.5 главами об этом в книге).

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

#books@ergonomic_code #functional_architecture@ergonomic_code #fp@ergonomic_code #js@ergonomic_code
👍12
Эргономичный код
Привет! По совету подписчика начал читать Grokking Simplicity. Пока прочитал 200 страниц из 600, но уже не могу удержать в себе восторг. Это лучшая известная мне книга по функциональному стилю (или скорее data-oriented programming), с лучшим известным мне…
Привет!

Дочитал книгу. По традиции, тема разработки бэков поверх РСУБД практически не раскрыта (этому посвящено примерно 10 страниц про луковую архитектуру), но в остальном - чудесная книга, мой новый лидер среди книг по ФП.

И сейчас мой рекомендуемый трек по изучению разработки бэков в функциональном стиле выглядит так:
1. Grokking Simplicity
2. Принципы юнит тестирования
3. Domain Modeling Made Functional
4. Структура и интерпретация компьютерных программ
5. Functional Design: Principles, Patterns, and Practices
6. Structured Design

#books@ergonomic_code #functional_architecture@ergonomic_code #fp@ergonomic_code #js@ergonomic_code
👍10
Привет!

Прочитал Java to Kotlin: A Refactoring Guidebook - мне понравилась.
Её с тем же успехом можно было назвать "Рефакторинг императивного стиля в функциональный" и она хорошо дополняет Grokking Simplicity - на мой вкус менее фундаментальная, но более бакэндерская и со статической типизацией. Хотя, опять же, тема персистанса практически не раскрыта.

И в качестве инструкции по переходу на Котлин она тоже хороша.
Рекомендую, в общем.

Ещё пару находок оттуда:
1. Идея "волокон" (grains) языков программирования. "Вдоль" которых работать проще, чем поперёк - как с деревом. И ФП укладывается вдоль волокон Котлина, но идёт поперёк волокон Джавы. С одной стороны. С другой стороны, монады - не укладываются в волокна Котлина.

2. У Фаулера есть статья про баги вызванные алиасингом

3. Один из соавторов этой книги - также соавтор и Growing Object-Oriented Software Guided by Tests - книги, которую я долгое время считал идеологически вредной. В Java to Kotlin же он пишет, что в GOOS моки не предполагалось использовать в качестве стабов - поставщиков данных через ридонли методы. Возможно, мне стоит перечитать GOOS и поменять своё мнение о ней.

#books@ergonomic_code #functional_architecture@ergonomic_code #kotlin@ergonomic_code #java@ergonomic_code
👍6
Привет!

Вышли результаты ежегодного опроса девелоперов от SO.

И там я нашёл новый аргумент за ФП - из топ-10 языков по ЗП 6 являются функциональными:)

А из оставшихся 4ёх только Руби не является ещё большей эзотерикой, чем ФП языки из топа:)

И ещё любопытное наблюдение - судя по всему, чем популярнее язык, тем меньше за него платят.
Вам ещё нужны аргументы в пользу функционального стиля?
Anonymous Poll
38%
Да, я чёт сомневаюсь
30%
Да, я сам не сомневаюсь, но команду ещё не убедил
33%
Горошчек не вари
Привет!

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

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

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

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

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

Надеюсь, в течении пары месяцев напишу развёрнутый пост на эту тему. После поста "Почему ФП" - там у меня тоже появилась идея:)

#immutable_domain_model@ergonomic_code
👍6🤔1
Привет!

Наткнулся на любопытную штуку для фронта - Feature-Sliced Design, "Architectural methodology for frontend projects".

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

#guideline@ergonomic_code
Привет!

Вечная битва добра и зла продолжается. Ведущий разработчик Spring Data Relational пинает JPA за сложность предсказания его поведения

Подача/запись доклада паршивые, но сам доклад хорош тем, что:
1. Подсвечивает пачку граблей JPA, для тех кто его юзает
2. Чуть подробнее раскрывает мою мысль из предпредыдущего поста, почему сложно реализовать хранение императивной ОО-модели

#talks@ergonomic_code #whynotjpa@ergonomic_code
2025/10/22 15:49:13
Back to Top
HTML Embed Code: