Привет!
Я посмотрел 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 🤷♂️ И я до сих пор не понимаю, чем
И эта разница навела меня на новый аргументпротив 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
Я посмотрел 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 основными сложностями будут изучить саму 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
YouTube
Migrating from (Spring Data) JPA to Spring Data JDBC by Jens Schauder @ Spring I/O 2024
Spring I/O 2024 - 30-31 May, Barcelona
Slides: https://2024.springio.net/slides/migrating-from-spring-data-jpa-to-spring-data-jdbc-springio24.pdf
A long long time ago in a city far away Jens Schauder started coding on a desktop calculator programmable in…
Slides: https://2024.springio.net/slides/migrating-from-spring-data-jpa-to-spring-data-jdbc-springio24.pdf
A long long time ago in a city far away Jens Schauder started coding on a desktop calculator programmable in…
👍7❤6
Привет!
Существует расхожее мнение, что разработчик большую часть жизни проводит влегаси браун филд проектах.
Но моя карьера его опровергает.
Первые 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
Существует расхожее мнение, что разработчик большую часть жизни проводит в
Но моя карьера его опровергает.
Первые 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
👍6❤5
Привет!
Недавно в комментах спрашивали про аргументы для бизнеса в пользу перехода на Котлин - они есть в этом докладе.
На мой взгляд их можно свести к паре слайдов
#talks@ergonomic_code #whykotlin@ergonomic_code
Недавно в комментах спрашивали про аргументы для бизнеса в пользу перехода на Котлин - они есть в этом докладе.
На мой взгляд их можно свести к паре слайдов
#talks@ergonomic_code #whykotlin@ergonomic_code
👍6👎1
Привет!
Я как всегда облажался с оценкой оверхеда на сетап проекта и сроки по Проекту Р начали подгорать.
Поэтому на этой недели не расскажу, как поднимаю БД на 300+ таблиц, собираемых из 8 лет миграций меньше чем за пару секунд.
Но быстренько поделюсь другой полезняшкой - при работе над новым демо проектом я накопал, что в jdbc url тестконтейнеров завезли поддержку и реюза, и темпфса.
А с учётом того, что померяв ещё чуть-чуть я отказался от схемы с предзапуском контейнеров, теперь можно все приседания с ручным запуском контейнера и прокидыванием его в контекст заменить на одну строчку
#tdd@ergonomic_code #integration_tests@ergonomic_code #project_r@ergonomic_code
Я как всегда облажался с оценкой оверхеда на сетап проекта и сроки по Проекту Р начали подгорать.
Поэтому на этой недели не расскажу, как поднимаю БД на 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
Telegram
Эргономичный код
Привет!
Существует расхожее мнение, что разработчик большую часть жизни проводит в легаси браун филд проектах.
Но моя карьера его опровергает.
Первые 12 лет работы в найме, мне действительно приходилось довольно много работать с чужим кодом: я поработал…
Существует расхожее мнение, что разработчик большую часть жизни проводит в легаси браун филд проектах.
Но моя карьера его опровергает.
Первые 12 лет работы в найме, мне действительно приходилось довольно много работать с чужим кодом: я поработал…
👍3
Привет!
Сроки по Проекту Р уже полыхают синим пламенем но я, тем не менее, повыкраивал по чуть-чуть времени на микропост с описанием того, как я добился сетапа свежей БД на 300+ таблиц за 1.5 секунды.
#ergo_testing@ergonomic_code #tdd@ergonomic_code #integration_tests@ergonomic_code #project_r@ergonomic_code
Сроки по Проекту Р уже полыхают синим пламенем но я, тем не менее, повыкраивал по чуть-чуть времени на микропост с описанием того, как я добился сетапа свежей БД на 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
По совету подписчика начал читать Grokking Simplicity.
Пока прочитал 200 страниц из 600, но уже не могу удержать в себе восторг.
Это лучшая известная мне книга по функциональному стилю (или скорее data-oriented programming), с лучшим известным мне разбором двух основополагающих принципов проектирования:
1. разделение ввода-вывода и бизнес-логики
2. использование одного уровня абстракции в функции (анкл Бобовскя заметка на эту тему в чистом коде - даже близко не лежала с 1.5 главами об этом в книге).
Настоятельно рекомендую прочитать эту книгу всем, с опытом коммерческой работы от года и до бесконечности.
#books@ergonomic_code #functional_architecture@ergonomic_code #fp@ergonomic_code #js@ergonomic_code
Manning Publications
Grokking Simplicity - Eric Normand
This practical guide will change the way you approach software design and development. It shows you how to write software that keeps complexity close to its inherent minimum.
👍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 страниц про луковую архитектуру), но в остальном - чудесная книга, мой новый лидер среди книг по ФП.
И сейчас мой рекомендуемый трек по изучению разработки бэков в функциональном стиле выглядит так:
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
Manning Publications
Grokking Simplicity - Eric Normand
This practical guide will change the way you approach software design and development. It shows you how to write software that keeps complexity close to its inherent minimum.
👍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
Прочитал 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
Java to Kotlin
Java to Kotlin: A Refactoring Guidebook
Supplementary resources
👍6
Привет!
Вышли результаты ежегодного опроса девелоперов от SO.
И там я нашёл новый аргумент за ФП - из топ-10 языков по ЗП 6 являются функциональными:)
А из оставшихся 4ёх только Руби не является ещё большей эзотерикой, чем ФП языки из топа:)
И ещё любопытное наблюдение - судя по всему, чем популярнее язык, тем меньше за него платят.
Вышли результаты ежегодного опроса девелоперов от SO.
И там я нашёл новый аргумент за ФП - из топ-10 языков по ЗП 6 являются функциональными:)
А из оставшихся 4ёх только Руби не является ещё большей эзотерикой, чем ФП языки из топа:)
И ещё любопытное наблюдение - судя по всему, чем популярнее язык, тем меньше за него платят.
Вам ещё нужны аргументы в пользу функционального стиля?
Anonymous Poll
38%
Да, я чёт сомневаюсь
30%
Да, я сам не сомневаюсь, но команду ещё не убедил
33%
Горошчек не вари
Привет!
У меня тут появилась идея, в чём ключевая разница между объектно-ориентированной моделью данных и функциональной, которая с одной стороны ставит всё на свои места, а, с другой, объясняет почему функциональная модель проще в реализации, понимании и использовании.
В ОО-модели сущность (якобы) инкапуслирована в объектах, а репозы/дао/объекты таблиц - это просто индексные указатели, которые используются для поиска объектов. И чтобы поменять объект, вам надо его найти, позвать пару сеттеров и (теоретически) готово.
В функциональной же модели (когда информация хранится в неизменяемых записях внутри изменяемых мап) сущность инкапсулирована репозах. И когда вы вы запрашиваете из репоза информацию о сущности - вы получаете запись о её текущем состоянии, которая отвязана от самой сущности. И чтобы изменить сущность вам надо обратиться к репозу и попросить его изменить сущность.
Как видно, функциональная модель в точности повторяет то, как сейчас на самом деле хранятся данные -- именно СУБД является владельцем данных, и когда вы вытягиваете в свой процесс массив байт с описанием текущего состояния БД, он не как не связан с теми байтами на диске, где живёт сущность.
ОО же модель и ОРМы пытаются сделать вид, как будто сущность инкапуслирована в объектах. И чтобы это попытаться сделать требуются титанические усилия в виде персистанс контекста, модели состояний сущностей, проксей и дёрти чекинга. И всё равно это всё течёт - у вас вполне может появится в процессе два разных объекта, якобы инкапсулирующих одну сущность. И если сеттер у вас не взорвался с исключением, это ещё не значит, что сущность на самом деле обновилась.
Надеюсь, в течении пары месяцев напишу развёрнутый пост на эту тему. После поста "Почему ФП" - там у меня тоже появилась идея:)
#immutable_domain_model@ergonomic_code
У меня тут появилась идея, в чём ключевая разница между объектно-ориентированной моделью данных и функциональной, которая с одной стороны ставит всё на свои места, а, с другой, объясняет почему функциональная модель проще в реализации, понимании и использовании.
В ОО-модели сущность (якобы) инкапуслирована в объектах, а репозы/дао/объекты таблиц - это просто индексные указатели, которые используются для поиска объектов. И чтобы поменять объект, вам надо его найти, позвать пару сеттеров и (теоретически) готово.
В функциональной же модели (когда информация хранится в неизменяемых записях внутри изменяемых мап) сущность инкапсулирована репозах. И когда вы вы запрашиваете из репоза информацию о сущности - вы получаете запись о её текущем состоянии, которая отвязана от самой сущности. И чтобы изменить сущность вам надо обратиться к репозу и попросить его изменить сущность.
Как видно, функциональная модель в точности повторяет то, как сейчас на самом деле хранятся данные -- именно СУБД является владельцем данных, и когда вы вытягиваете в свой процесс массив байт с описанием текущего состояния БД, он не как не связан с теми байтами на диске, где живёт сущность.
ОО же модель и ОРМы пытаются сделать вид, как будто сущность инкапуслирована в объектах. И чтобы это попытаться сделать требуются титанические усилия в виде персистанс контекста, модели состояний сущностей, проксей и дёрти чекинга. И всё равно это всё течёт - у вас вполне может появится в процессе два разных объекта, якобы инкапсулирующих одну сущность. И если сеттер у вас не взорвался с исключением, это ещё не значит, что сущность на самом деле обновилась.
Надеюсь, в течении пары месяцев напишу развёрнутый пост на эту тему. После поста "Почему ФП" - там у меня тоже появилась идея:)
#immutable_domain_model@ergonomic_code
👍6🤔1
Привет!
Наткнулся на любопытную штуку для фронта - Feature-Sliced Design, "Architectural methodology for frontend projects".
На первый взгляд там вроде никаких откровений нет, но себе утащил в качестве вдохновения как оформить ЭП. Когда наконец начну это делать
#guideline@ergonomic_code
Наткнулся на любопытную штуку для фронта - Feature-Sliced Design, "Architectural methodology for frontend projects".
На первый взгляд там вроде никаких откровений нет, но себе утащил в качестве вдохновения как оформить ЭП. Когда наконец начну это делать
#guideline@ergonomic_code
feature-sliced.design
Welcome | Feature-Sliced Design
Architectural methodology for frontend projects
Привет!
Вечная битва добра и зла продолжается. Ведущий разработчик Spring Data Relational пинает JPA за сложность предсказания его поведения
Подача/запись доклада паршивые, но сам доклад хорош тем, что:
1. Подсвечивает пачку граблей JPA, для тех кто его юзает
2. Чуть подробнее раскрывает мою мысль из предпредыдущего поста, почему сложно реализовать хранение императивной ОО-модели
#talks@ergonomic_code #whynotjpa@ergonomic_code
Вечная битва добра и зла продолжается. Ведущий разработчик Spring Data Relational пинает JPA за сложность предсказания его поведения
Подача/запись доклада паршивые, но сам доклад хорош тем, что:
1. Подсвечивает пачку граблей JPA, для тех кто его юзает
2. Чуть подробнее раскрывает мою мысль из предпредыдущего поста, почему сложно реализовать хранение императивной ОО-модели
#talks@ergonomic_code #whynotjpa@ergonomic_code
Привет!
Я тут такую штуку в Котлине откапал.
Для локальных и возвращаемых из приватных функций анонимных объектов можно обращаться к поля
Что тут просиходит:
1. У меня есть функция createTest, которая возвращает анонимный объект с полем id
2. Я генерирую список таких объектов и сохраняю его в tests
3. Я беру первый элемент из списка и беру у него поле id. И всё работает. Но если попытаться проставить тип для функции или коллекции - там можно вставить только Any (aka Object) и всё ломается.
У меня есть сомнения в целесообразоности использования такого трюка, но код ручного маппинга 1-N в дерево неизменяемых объектов он мне сделал чуть понагляднее
#kotlin@ergonomic_code
Я тут такую штуку в Котлине откапал.
Для локальных и возвращаемых из приватных функций анонимных объектов можно обращаться к поля
fun test() {
val tests = (1..2).map {
createTest(mapOf("id" to 10))
}
println(tests[0].id == 10L)
}
private fun createTest(map: Map<String, Any>) = object {
val id: Long = map["id"] as Long
}Что тут просиходит:
1. У меня есть функция createTest, которая возвращает анонимный объект с полем id
2. Я генерирую список таких объектов и сохраняю его в tests
3. Я беру первый элемент из списка и беру у него поле id. И всё работает. Но если попытаться проставить тип для функции или коллекции - там можно вставить только Any (aka Object) и всё ломается.
У меня есть сомнения в целесообразоности использования такого трюка, но код ручного маппинга 1-N в дерево неизменяемых объектов он мне сделал чуть понагляднее
#kotlin@ergonomic_code
👍3
Привет!
У меня две новости. Обе хорошие и обе объясняют затишье в канале:)
Новость первая - в июле у меня родился второй ребёнок.
Поэтому времени на ЭП стало меньше. Минимум на ближайший год, а то и два.
Новость вторая - мой доклад "Spring Data JDBC. Четыре года в проде, полет отличный" взяли в программу Joker 2024.
Поэтому сейчас всё ЭП-время уходит на подготовку доклада и до октября в канале я буду постить только ссылки на видосы, которые смотрю, пока гуляю с ребёнком:)
Если собираетесь на Joker и ещё не купили билеты - не торопитесь, в прошлый раз мне чуть меньше чем за месяц до конфы дали промокод на скидку 20%
#talks@ergonomic_code
У меня две новости. Обе хорошие и обе объясняют затишье в канале:)
Новость первая - в июле у меня родился второй ребёнок.
Поэтому времени на ЭП стало меньше. Минимум на ближайший год, а то и два.
Новость вторая - мой доклад "Spring Data JDBC. Четыре года в проде, полет отличный" взяли в программу Joker 2024.
Поэтому сейчас всё ЭП-время уходит на подготовку доклада и до октября в канале я буду постить только ссылки на видосы, которые смотрю, пока гуляю с ребёнком:)
Если собираетесь на Joker и ещё не купили билеты - не торопитесь, в прошлый раз мне чуть меньше чем за месяц до конфы дали промокод на скидку 20%
#talks@ergonomic_code
Joker 2024. Java-конференция для опытных разработчиков
Структурный дизайн. Древний секрет простого и быстрого кода | Доклад на Joker 2024
Дам краткий экскурс в структурный дизайн и, в частности, в понятие сбалансированных систем.
На примере трех реальных кейсов размером от 50 до 40 000 строк кода покажу, как выглядят несбалансированные системы и к каким проблемам ведет дисбаланс.
Затем покажу…
На примере трех реальных кейсов размером от 50 до 40 000 строк кода покажу, как выглядят несбалансированные системы и к каким проблемам ведет дисбаланс.
Затем покажу…
🔥17❤2👍2
Ну и собственно очередной досмотренный видос - Test automation without a headache: Five key patterns.
Мне понравился, рекомендую.
Паттерны:
1. разделяйте ожидания, workflows и взаимодействия - эту штуку я с наскоку не понял, но кажется в ней что-то есть, буду разбираться.
2. Симулируйте только те штуки, которые вы полностью понимаете. Это классика из Growing Object-Oriented Software, что мокать можно только собственные классы.
3. Делайте очевидной связь входов с выходами. Я с этим тезисом согласен и у себя тоже стараюсь делать это, но как это делать системно пока не придумал.
4. Оптимизируйте для решения проблем, не для скорости написания тестов. Тут докладчик говорит об оптимизизации времени поиска причин падения теста, а я бы ещё добавил и оптимизацию времени поддержки тестов при рефакторинге - в идеале оно должно равняться нулю
5. Реорганизуйте тесты для discovery. Посыл вроде как "организуйте тесты не воркуг юзер стори/итераций, а вокруг функциональности". Но лично я ни разу не видел первый вариант.
Есть ещё версия на ютубе с субтитрами и короче на 25 минут
#talks@ergonomic_code #tdd@ergonomic_code
Мне понравился, рекомендую.
Паттерны:
1. разделяйте ожидания, workflows и взаимодействия - эту штуку я с наскоку не понял, но кажется в ней что-то есть, буду разбираться.
2. Симулируйте только те штуки, которые вы полностью понимаете. Это классика из Growing Object-Oriented Software, что мокать можно только собственные классы.
3. Делайте очевидной связь входов с выходами. Я с этим тезисом согласен и у себя тоже стараюсь делать это, но как это делать системно пока не придумал.
4. Оптимизируйте для решения проблем, не для скорости написания тестов. Тут докладчик говорит об оптимизизации времени поиска причин падения теста, а я бы ещё добавил и оптимизацию времени поддержки тестов при рефакторинге - в идеале оно должно равняться нулю
5. Реорганизуйте тесты для discovery. Посыл вроде как "организуйте тесты не воркуг юзер стори/итераций, а вокруг функциональности". Но лично я ни разу не видел первый вариант.
Есть ещё версия на ютубе с субтитрами и короче на 25 минут
#talks@ergonomic_code #tdd@ergonomic_code
Vimeo
Test automation without a headache: Five key patterns - Gojko Adzic
Writing maintainable test automation code is today as important as being able to design good customer-facing systems, yet very few teams do it well. If you think…
Привет!
Прочитал Good to Great: Why Some Companies Make the Leap...And Others Don't
В книге описывают результаты исследования, где взяли 11 контор, стоимость акций которых 15 лет росла как рынок, а с определённого момента 15 лет подряд росла минимум в три раза быстрее рынка;
Для этих контор взяли 11 контор из тех же индустрий, которые 30 лет росли не лучше рынка;
И ещё взяли 6 контор, у которых был переломный момент, но 3ёх-кратный рост продлился менее 15 лет.
А потом попытались понять, чем 11 "good-to-great", контор похожи между собой и отличаются от остальных.
И вроде как поняли и описали что надо делать, чтобы забацать "great company".
И среди прочего, как это не удивительно, надо собрать правильных людей.
А правильные люди - это не те, которые прямо сейчас обладают нужными вам скиллами, а те, которые обладают характером, нужным для вашей организации.
И на мой взгляд это даёт ответ на вопрос, что надо спрашивать на собесах - алгоритмы и технологии или книги и петпроекты и прочие вопросы "за жизнь".
#books@ergonomic_code #hr@ergonomic_code
Прочитал Good to Great: Why Some Companies Make the Leap...And Others Don't
В книге описывают результаты исследования, где взяли 11 контор, стоимость акций которых 15 лет росла как рынок, а с определённого момента 15 лет подряд росла минимум в три раза быстрее рынка;
Для этих контор взяли 11 контор из тех же индустрий, которые 30 лет росли не лучше рынка;
И ещё взяли 6 контор, у которых был переломный момент, но 3ёх-кратный рост продлился менее 15 лет.
А потом попытались понять, чем 11 "good-to-great", контор похожи между собой и отличаются от остальных.
И вроде как поняли и описали что надо делать, чтобы забацать "great company".
И среди прочего, как это не удивительно, надо собрать правильных людей.
А правильные люди - это не те, которые прямо сейчас обладают нужными вам скиллами, а те, которые обладают характером, нужным для вашей организации.
Second, widen your definition of “right people” to focus more on the character attributes of the person and less on specialized knowledge. People can learn skills and acquire knowledge, but they cannot learn the essential character traits that make them right for your organization
И на мой взгляд это даёт ответ на вопрос, что надо спрашивать на собесах - алгоритмы и технологии или книги и петпроекты и прочие вопросы "за жизнь".
#books@ergonomic_code #hr@ergonomic_code
🔥2
Привет!
Пошёл полистать Lean Architecture в поисках инфы как писать юзкейсы и вообще форматов описания требований.
И потихоньку переполз на DCI.
И в это прочтение у меня три новых мысли возникло.
Мысль первая
Тезис, что ООП - это то как мир представляют нормальные люди - фикция.
ООП, по определению объекта (состояние + поведение), предполагает активность объектов.
Например счёт может (сам) сделать перевод. Или напечатать себя.
Но обычные пользователи (в лице моей жены) не мыслят категориями, что счёт сам переводит деньги или сам себя печатает. Они (она) мыслит скорее категориями 19-ого века, где есть карточка с информацией о счёте, и служащий банка, который выполняет её поручения по переводу денег или печати счёта.
Наверное поэтому, "полнокровная" доменная модель не вытеснила анемичную доменную модель в мейнстриме. Тупые сущности и умные сервисы - это то, как наши пользователи думают о наших информационных системах.
Мысль вторая
Возможно, за всей этой движухой лежит желание получить полиморфное поведение - удобно же иметь PrintableAccount, который можно использовать в обработчике "Напечатать выписку" и не парится когда, появляется новый тип счёта.
Но это не удобно, когда появляется новая операция над счётом (закрыть, например) - тогда придётся писать код закрытия счёта в пачке классов, а не одной функции.
Это типовой пример Expression problem (aka Data/Object Anti-Symmetry из 6ой главы чистого кода).
И, наверное, ООП и правда стрельнуло только на волне GUI - там как раз чаще появлялись новые типы, чем новые методы.
Но на бэке информационной системы, намного чаще появляются новые операции, чем типы.
Поэтому "полнокровная" доменная модель ведёт не только к тому, что изменения приходится вносить в множество мест, но ещё и к огромным с десятками методов для совершенно разных контекстов объектов с низким cohesion и высоким coupling.
Мысль третья
DCI - это ещё одна попытка решить expression problem.
И если у вас её нет (а у меня нет - очень редко появляются иерархии типов сущностей) - то и DCI не надо.
#whynotoop@ergonomic_code #dci@ergonomic_code #lean_architecture@ergonomic_code
Пошёл полистать Lean Architecture в поисках инфы как писать юзкейсы и вообще форматов описания требований.
И потихоньку переполз на DCI.
И в это прочтение у меня три новых мысли возникло.
Мысль первая
Тезис, что ООП - это то как мир представляют нормальные люди - фикция.
ООП, по определению объекта (состояние + поведение), предполагает активность объектов.
Например счёт может (сам) сделать перевод. Или напечатать себя.
Но обычные пользователи (в лице моей жены) не мыслят категориями, что счёт сам переводит деньги или сам себя печатает. Они (она) мыслит скорее категориями 19-ого века, где есть карточка с информацией о счёте, и служащий банка, который выполняет её поручения по переводу денег или печати счёта.
Наверное поэтому, "полнокровная" доменная модель не вытеснила анемичную доменную модель в мейнстриме. Тупые сущности и умные сервисы - это то, как наши пользователи думают о наших информационных системах.
Мысль вторая
Возможно, за всей этой движухой лежит желание получить полиморфное поведение - удобно же иметь PrintableAccount, который можно использовать в обработчике "Напечатать выписку" и не парится когда, появляется новый тип счёта.
Но это не удобно, когда появляется новая операция над счётом (закрыть, например) - тогда придётся писать код закрытия счёта в пачке классов, а не одной функции.
Это типовой пример Expression problem (aka Data/Object Anti-Symmetry из 6ой главы чистого кода).
И, наверное, ООП и правда стрельнуло только на волне GUI - там как раз чаще появлялись новые типы, чем новые методы.
Но на бэке информационной системы, намного чаще появляются новые операции, чем типы.
Поэтому "полнокровная" доменная модель ведёт не только к тому, что изменения приходится вносить в множество мест, но ещё и к огромным с десятками методов для совершенно разных контекстов объектов с низким cohesion и высоким coupling.
Мысль третья
DCI - это ещё одна попытка решить expression problem.
И если у вас её нет (а у меня нет - очень редко появляются иерархии типов сущностей) - то и DCI не надо.
#whynotoop@ergonomic_code #dci@ergonomic_code #lean_architecture@ergonomic_code
👍4
Мысль четвёртая
А ну и мысль четвёртая - если вы пишите бэки - вам надо ФП/ФА, а не ООП/DCI :)
Точнее DOP/ФА как здесь, а не чистый ФП как здесь
#dop@ergonomic_code #oop@ergonomic_code #fp@ergonomic_code
А ну и мысль четвёртая - если вы пишите бэки - вам надо ФП/ФА, а не ООП/DCI :)
Точнее DOP/ФА как здесь, а не чистый ФП как здесь
#dop@ergonomic_code #oop@ergonomic_code #fp@ergonomic_code
GitHub
Project-Mariotte/src/main/kotlin/mariotte/apps/guest/reservations/ReserveRoomOperation.kt at master · ergonomic-code/Project-Mariotte
Демонстрационный проект Эргономичного подхода - сервис бронирования номеров в отелях - ergonomic-code/Project-Mariotte
👍1