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

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

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

Продолжаю проверять гипотезу, что это у меня проблема в ДНК, а с агрегатами и Spring Data JDBC всё ок, смотрю очередной видос

Всё тот же автор Spring Data JDBC одновременно:
1) пинает JPA
2) восторгается агрегатами
3) предлагает декомпозировать систему на основе агрегатов
4) запрещает циклы в зависимостях
Смотрю как в своё зеркало 21ого года:)

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

Ну и наконец:
"it will feel painfull ... but people have to think where stuff belongs and this alone is I think a great benefit"
Со второй частью согласен полностью. Но хочется найти способ обойтись без боли

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

Сегодня линкопост: Functional Programming for Pragmatists
Мужик говорит быстро, поэтому слушать довольно тяжело, но мне нравится его определение и объяснение ФП.

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

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

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

#talks@ergonomic_code #fp@ergonomic_code
Между тем в фоновом режиме думаю как делать эргономичный персистанс и накопал статью с критикой SQL-я за неэргономичность:) И альтернативным предложением:)
Может быть у нас всё-таки есть свет в конце туннеля:)

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

Вы наверняка слышали, что Хоар назвал null-ы своей ошибкой на миллиард долларов.

Вчера случайно наткнулся на относительно свежую (2009 год) презентацию самого Хоара на эту тему.
И она натолкнула меня на мысль, что мы живём на закате (первой?) золотой эры ИТ - всё самое крутое придумали в 60-70-ые годы и многие из тех, кто это ещё живы и при на них можно посмотреть в живую:)

Сама же презентация не то чтобы прям полезная была, но довольно интересная и за ней можно скоротать длинный зимний вечерок:)

#talks@ergonomic_code
Привет!

Снова линко-пост.

Тут дядька хорошо показывает в чём проблема с наллами и предлагает заменить их на Maybe-монаду (ака Java Optional, ака sum типы).

Но не спешите всё переписывать на Optional, пока не посмотрите как Рич Хикки пинает Maybe в первых 14 минутах этой презентации и предлагает заменить их на union типы (ака Kotlin nullable, ака Java Multiple catch block).

А этой статье автор подробно рассматривает sum & union типы и приходит к выводу, что "Therefore union types are strictly more flexible than sum types, but the ergonomics of each approach depends on the use-case."

#talks@ergonomic_code
Небольшой тизер нового поста - проблемы с производительностью, присущие системам на базе мейнстримовых ОРМов (JPA) являются следствием проблем дизайна (высокая связанность и циклы в связях между модулями), порождённых использованием этих ОРМов.
Привет!

Пока новый пост варится - радую вас линками:)

Я нашёл базу данных мечты - EdgeDb.

Что в ней крутого:
1) Она на базе Постгреса. Т.е. ядро надёжное и если с верхним слоем будут проблемы - можно будет цепануться к Постгресу напрямую
2) У неё графово-реляионна модель данных
2.1) Она поддерживает вложенные инсёрты
2.2) Она поддерживает наследование и полиморфные связи
2.3) Она поддерживает выборку иерархичных данных
2.4) Запросы на EdgeQL композируемые (Composable)
3) Судя по гиту, пилят её уже 13 лет и сейчас пилят активно как никогда - на момент написания предыдущий мёрж в мастер был 43 минуты назад, а за последние 2 дня вмёржили 20 ПРов
4) Free как и свобода и как пиво
5) Поддерживает GraphQL из коробки
6) У неё релиз версии 1.0 в феврале

Одна проблема - нет клиентов под JVM 😂

#posts@ergonomic_code #ergo_persistance@ergonomic_code #tools@ergonomic_code #databases@ergonomic_code
Привет!

Внезапный "а знаете ли вы пост?".

Наверняка вы слышали, что при проектировании REST API необходимо отдавать предпочтение стандартизированный штукам, например для авторизации использовать заголовок Authentication.

Чего вы, возможно, не слышали (по крайней мере я не слышал до вчерашнего дня) - ответы на запросы с заголовком Authentication запрещено кэшировать по умолчанию. А если использовать доморошенные заголовки, то надо не забыть явно запретить кэширование ответов.

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

Объявляю идейный кризис эргономичного подхода успешно преодолённым:) В частности с агрегатами и Spring Data JDBC всё так, это у меня была ошибка в ДНК.

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

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

Эргономичный подход стоит на трёх столпах:
1) Декларативный стиль программирования
* Это позволяет минимизировать связанность по общей области и управлению (common & control coupling)
2) Декомпозиция системы на модули с высокой связностью и низкой связанностью
* Это и делает систему простой для понимания и лёгкой в поддержке
3) Детройтская школа тестирования
* Это минимизирует связанность между тестами и деталями реализации

От мейнстримового подхода Эргономичный подход отличается следующим:
1) Использование модели неизменяемых связанных данных (Immutable Relation Data) на базе агрегатов DDD и эпохальной модели времени для моделирования информации системы (а не модели графа изменяемых объектов)
2) Стремление максимум кода вынести в функции без побочных эффектов (а не бессистемное разбрасывание побочных эффектов по всему коду)
3) Применение архитектурного стиля функциональное ядро/императивная оболочка (а не классической слоёной архитектуры)
4) Разделение слоя бизнес-логики на подслой приложения (оркестрация выполнения операции системы) и подслой предметной области (сложные бизнес-правила, задействующие несколько агрегатов) (а не единый слой сервисов)
5) Верхнеуровневое разбиение на модули системы (а не слои)
6) Минимизация зависимостей между модулями системы (а не произвольное добавление новых зависимостей в систему)
7) Тестирование системы на соответствие требованиям (а не покрытие тестами классов и методов)
8) Мокирование только дорогих или нестабильных внешних систем (а не всех классов, помимо тестируемого)
9) Для достижения пп 1-3 и 6 - использование Spring Data JDBC (а не Spring Data JPA)
10) Для достижения п. 6 - ручное управление зависимостями (а не Spring Component Scan)

P. S>
это ещё и линко пост был:)
Immutable Relational Data - коротенько (30 минут) о там как жить с неизменяемой моделью данных (в данном конкретном случае на примере веб-фронта на Elm-е)
эпохальная модель времени - как моделировать изменения в неизменяемой модели данных

P.P.S>
Промахунлся:(

#immutable_domain_model@ergonomic_code #ergo_approach@ergonomic_code
Привет!

Отвлёкся от поста про агрегаты, чтобы быстро написать свою версию ответа на вопрос "Что почитать по проектированию приложений?"

#books@ergonomic_code
Привет!

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

Итем 1
(Уже вчера) вышел Котлин 1.6.20 с превью фичи множества ресиверов (дизайн фичи)
Фича довольно жёсткая - даже не буду пытаться тут на пальцах её объяснять.
Поэтому, не уверен, что несёт больше пользы, чем вреда (см сколько "не делайте так" в дизайне).
Но если аккуратно применять, то позволит писать ещё более выразительные ДСЛи

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

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

Зато, подумал, что если бы у меня были только функции, в том числе высшего порядка, то мне было бы намного проще объяснить.
Попробовал объяснить это жене (она 15 лет назад прошла курс по ООП, а сейчас продвинутый пользователь экселя) - и про функции мы смогли нормально поговорить, а с объектами очень быстро дошли до "ой всё":)
И у меня нет ощущения, что сложность ООП как-то окупается.

В общем ФП - наше всё:)

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

А тут я добрался наконец до дисера по REST и там чуть ли не на первой странице Филдинг пишет:
> The hyperbole of The Architects Sketch may seem ridiculous, but consider how often we see software projects begin with adoption of the latest fad in architectural design, and only later discover whether or not the system requirements call for such an architecture. Design-by-buzzword is a common occurrence

22 года спустя, заказчики всё ещё продолжают требовать делать модную, а не обоснованную требованиями архитектуру...
Привет!

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

ТЛДР- мальчик становится мужчиной 5-летний "техлид" начинает понимать суть своего карго культа, нахапанного в интернете, и встаёт на путь к эргономичному подходу:)

А теперь подробнее:)

Во-первых, заголовок явно кликбейтный (или как оно называется?). Я работал с кодом стартапа из долины и постоянно читаю про "зарубежный опыт" - у них там буквально всё тоже самое, один в один.
Во-вторых, это личное мнение одного автора, а не всего "зарубежа".
В-третьих, автор закончил в универ в 17ом году - а я не верю в техлидов с 5 годами опыта (добавка после прочтения поста - и правильно делаю, что неверю)
Но, справедливости ради, у него есть пост про отказ от юнит тестов - плюсик.


> For us, this has reduced the size of a regular feature, such as a new microservice endpoint for updating or reading data, from a total of approximately 25 files down to just 5, that’s an 80% reduction with the majority of code simply having been deleted, all while simultaneously improving code readability
Ох, ну у меня по дефолту на эндпоинт надо вообще 4-5 классов - контроллер, сервис приложения, репоз, агрегат и опциональный сервис домена
А на фоне оверхеда который приносят микросервисы всё что описано позже - экономия на спичках. Из поста не ясно, есть ли к системе требования, обосновывающие применение МС.

> meaning that we want to keep abstractions to a minimum and only introduce complexity when it provides a significant and real benefit
С этим тезисом в целом согласен - поэтому, например, отказался от чисто архитектуры по дефолту и практически никогда не завожу интерфейсы с одной реализацией.
С другой стороны, не опробовав на практике идею отказаться от сервисов-обёрток вокруг репозов, типа: fun findById(id: Long) = repo.findbyId(id), я снова начинаю склоняться к тому, что они всё-таки нужны для определения публичного интерфейса модуля. Но тут ещё буду думать.

> each class should only have one reason to change, or, they should only have one job
Чувак не понимает SRP
Но при том понимает, что SRP в его интерпретации - вреден - плюсик

Судя по второй картинке - он юзал заголовочные интерфейсы. Понял что это лишнее - плюсик
Судя по ней же - он поклонник карго культа - использует концепцию repository для read model. Насколько я знаю, не существует альтернативной ДДДшной и распространённой концепции репозитория. А в ДДД репозитории используются только для write-модели.

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

> Introducing various programming design patterns before their benefit is really needed is another common pitfall
вот поэтому техлиды должны иметь хотя бы лет 10 опыта - чтобы успеть наигарться во всякие прикольные штуки.
Я паттернами сейчас практически не пользуюсь.
Плюсик, что понял

> Another pattern used extensively is the Command and Publish-Subscribe Pattern
В целом согласен. Я видел как эвент басы используют для вызова методов в одном процессе - это характеризуется "событиями", названы как указания - SendHttpRequest(dest), ровно одним обработчиком "события", катастрофичными последствиями, если событие не будет обработано мгновенно.
Но если вам над расцепить слабосвязанные компоненты (т.е. вам ок, если обработчик сработает завтра) - то эвент бас один из основных инструментов для этого.

#posts@ergonomic_code #ergo_approach@ergonomic_code
> CQRS essentially implies that you have two separate data models ... The huge downside of this pattern is the fact that a whole separate data model needs to be built and maintained
С этим я и согласен и не согласен.
Я применяю разные модели для записи и чтения не столько из соображений производительности (что является следствием), сколько из соображений декомпозиции информации на управляемые кусочки. Но я согласен что это существенный оверхед, оправданность которого весьма спорна и ищу способы уменьшить его.
Так же, http - это одна из самых жёстких системных границ и если что и стоит усилий дизайна - так это хттп интерфейс. Особенно апи опубликовано (список клиентов не известен), либо среди клиентов есть мобильные приложения (которые невозможно обновить без согласия пользователя). И в этом случае использовать единую модель и внутри и в АПИ записи и в АПИ чтения - дорога в ад.

> Low coupling introduced everywhere
Парень забыл про high cohesion - coupling & cohesion всегда идут вместе
> An isolated feature does not need low coupling and interfaces between the elements inside it
Бинго! "isolated feature" по определению является высоко связной - а декаплинг реализации изолированной фичи запрещён конвенцией по правам фичей.

> Also, if you are merely using interfaces to allow mocking in tests, seriously consider switching to a mocking library that allows mocking concrete classes to avoid the overhead.
А вот тут парню ещё предстоит пролить пот и кровь - правильный ответ "следует отказаться от мокирования на уровне классов"

> If you are feeling particularly adventurous, you can go the extra mile and move separate classes into the same file
парень открыл рискованную штуку, рекомендованную в официальном соглашении о кодировании Котлина.

> This is essentially favoring a Vertical Slice Architecture over the more classical Onion Architecture
А вот он дошёл и до концептульной декомпозиции. Только непонятно почему он поместил это в раздел для особо смелых.

> For this reason, we have dropped this kind of unit testing entirely and opted for a completely different approach to automated testing
А вот он таки и дошёл до нормального тестирования.

И того, для того чтобы избавиться от 80% кода наши зарубежные коллеги открыли эргономичный подход:
1) интеграционное тестирование, вместо моков
2) концептуальная декомпозиция, вместо слоёной
3) заявка на декларативный стиль через разделения команд и запросов (CQRS), вместо повсеместного императивного стиля. Но тут нашим молодым западным коллегам ещё предстоит нас догнать, в понимании, что в императивных командах так же надо стремиться выделять декларативный трансформации

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

У меня есть две новости:)

1) Я собрал первый черновик поста про агрегаты. Он на 20 минут
2) К нему будет ещё 3 поста-приквела. И потом ещё будет отдельный пост сиквел с примером:)

Поэтому сегодня линка на чужой, но готовый пост по агрегатам:)

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

Тихой сапой прочитал Next Generation Databases.
В целом хорошее краткое изложение (по сути - 200 страниц с картинками) истории, текущего состояния и будущего систем хранения данных.
Книги уже 7 лет, но на удивление с тех пор ничего особо не поменялось.
Любопытный факт - по мнению автора РСУБД всё ещё лучший выбор для подавляющего большинства приложений.
Хотя архитектура всех основных современных РСУБД, уходящая корнями в System R 70-ых годов изрядно устарела.

О чём пишет Стоунбрейкер в The End of an Architectural Era (It's Time for a Complete Rewrite)
В этой статье он расписывает почему текущие архитектуры устарели и как надо по другому.
"По другому" можно уже сейчас попробовать в его VoltDB и Datomic Рича Хикки.

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

При том и VoltDB и Datomic требует, чтобы хранимки были чистыми. Так что ФП - наше всё.

Как вы понимаете, в этом канале я, конечно же, не могу не упомянуть эргономичный подход:)

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

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

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

В общем у нас впереди предстоит много интересного:)

#books@ergonomic_code #databases@ergonomic_code
⚡️Spring рекомендует концептуальную декомпозицию!
И называет это разумным способом структурирования приложения

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

#posts@ergonomic_code #ergo_arch@ergonomic_code #spring@ergonomic_code
Привет!

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

Для Джавы тоже есть встроенная СУБД - MicroStream. Но у них нет транзакций из коробки, хотя они позволяют атомарно сохранять несколько объектов

Ну и кубит тоже в ту же сторону:) Там прямо сейчас есть традиционное АПИ с begin-commit-rollback, но я его выпилю, как руки дойдут.

#ergo_persistance@ergonomic_code
Привет!

Мужик рассказывает про подход к разработке, очень близкий к эргономичному

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

Затем в середине он говорит о выделении кода в слой домена, и с учётом того, что работу с БД он оставляет на уровне выше, то этот код становится чистым и это всё очень начинает напоминать архитектуру функциональное ядро/императивную оболочку.

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

Я снова радуюсь тому, что 90% идей эргономичного подхода разделяют другие разработчики и тому, что я всё ещё вижу потребность в своей работе. На одном из слайдов видно, что мужик объединяет свои базовые кирпичики в некие "фичи", которые очень похожи на мои компоненты, но он не говорит о том как эти фичи находить. Я же - расскажу, покажу и дам практические советы, как эти компоненты-"фичи" находить. На самом деле тизер я уже дал практически год назад. За этот год я эту идею существенно продвинул и опробовал на нескольких проектах.

#talks@ergonomic_code
Привет!

Пока пост про агрегаты варится (настаивается уже), радую вас линко-постами:)

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

#posts@ergonomic_code #design@ergonomic_code