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

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

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

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

Но моя карьера его опровергает.
Первые 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
Привет!

Я как всегда облажался с оценкой оверхеда на сетап проекта и сроки по Проекту Р начали подгорать.
Поэтому на этой недели не расскажу, как поднимаю БД на 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
Привет!

История ужасов про мутабельное состояние.

Есть у нас тут в Проекте Р задачка по загрзуке файла. Отдали её юниору. Он вчера провозился весь день - не осилил загрузить, спринг ругается что не видит multipart part.

Сегодня подключился я. Сделал мастер-класс по ТДД, докинул пару параметров, тест (поверх MockMvc) прошёл. На всякий случай (не верю я этим мокам) пошёл перепроверить курлом - не работает.

Засучил рукава. Перелазил весь инет. Отдебажил эту хрень вплоть до org.apache.tomcat.util.http.fileupload.util.LimitedInputStream - я в запросе тело отправляю, а когда начинает работать StandardServletMultipartResolver - тело куда-то исчезает 😱🤯

Провозился три часа. Потом каким-то чудом, вспомнил, что у нас есть фильтр, который вычитывает тело и прокидыввает дальше обёртку, которая переопределяет getInputStream. А getParts - не переопределяет. И getParts пытается вычитать данные из инпутстрима оригинального HttpServletRequest. Из которого мы уже всё вычитали в фильтре. Занавес.

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

#whyfp@ergonomic_code #project_r@ergonomic_code
👍10😱2
Привет!

Периодически гипотезы, лежащие в основе ЭП, рушатся о жестокую реальность промышленной разработки, что приводит к кризисам ЭП, которых уже было три штуки: раз по мотивам проекта Barcoder (решение), два (решение) и три (решение - нафик ООД, ДДД и private внутри одного репоза😀) - по мотивам #project_e.

И вот по мотивам #project_r за последние 5 дней у меня случился и благополучно разрешился очередной кризис ЭП:)

В связи с чем у меня пачка новостей.

Книга
Это уже новость второй свежести, но для контекста надо проговорить - я договорился с менеджером проектов издательства Питер начать с апреля плотную работу над книгой про ЭП. Так что надеюсь, на горизонте пары лет книга увидит свет.

Отказ от ФА
Номинально самая большая новость - я решил отказаться от ФА (которая когда-то была одним из трёх столпов ЭП).
Но по сути ничего не меняется - ЭП всё так же предполагает использование неизменяемых структур данных и максимально возможное разделение логики и ио.
Это просто признание реальности, что в ЭП, который начинался как сильно функциональный, я методично отказываюсь от отличительных черт ФА/ФП:
1. уже очень давно я отказался от монад и ROP-а в пользу защитных условий
2. затем я затащил операции в императивную оболочку
3. во многом по мотивам Проекта Р я вернул в милость выброс исключений вместо возвращения Result
4. по мотивам Проекта Р, я утащил сбалансированную форму системы с архитектурного уровня системы, на локальный уровень отдельных методов

Отказ от SDJ как дефолтной технологии работы с БД
А вот по сути самое больше изменение - я решил отказаться от SDJ в качестве дефолта для работы с БД.
Это всё ёще допустимый в рамках ЭП т.к. его всё ещё легче "продать" заказчикам и коллегам, но по умолчанию я теперь предлагаю использовать какой-то легковесный DSL - jooq или Exposed, ещё не решил что именно.

Это опять же обусловлено опытом Проекта Р - там у меня львиная доля запросов чтения рукописные, потому что SDJ не в состоянии эффективно доставать данные этого проекта, а после того, как мне пришлось ещё и два кастомных метода сохранения написать - стало понятно, что я борюсь с технологией. Этому решению так же поспособствовали пост из канала одного из участников нашей группы.
И решение перейти на UUID-ы, которое так же было обусловлено опытом разработки Проекта Р, где надо сетапать огромные графы объектов в тестах и с генераций ИДов на уровне БД это очень сложно.

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

1. проекция структуры данных (модель данных) - тут про агрегаты и связи между ними
2. проекция состояния (объектная модель) - тут про объекты в рантайме (порты, операции, ресурсы) и связи между ними
3. проекция структуры поведения (процедурная модель) - тут про методы и связи между ними

Плюс я туда сразу накидал кучу примеров (пока на словах😕), а так же процессы построения всех этих структур и итоговой архитектуры.

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

И возвращаясь к книге - эта статья по сути - четверть книги. Заполнить там пробелы, добавить примеры и теоретическая часть по ЭА готова. Вспоминая про бейзкамповский Hill Chart, у меня сейчас такое ощущение, что я достиг холма реализации ЭА и дальше только дело техники. Лишь бы очередной проект не зафейлил очередную гипотезу 😄

#the_book@ergonomic_code #functional_architecture@ergonomic_code #ergo_arch@ergonomic_code #ergo_persistance@ergonomic_code #spring_data_jdbc@ergonomic_code
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥6👍42
Привет!

Ток что впервые за 4 года пришлось запилить руками dirty checking в SDJ...

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

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

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

5-ый кризис ЭП пролетел буквально за часик:)

Хотел написать я.
А потом упёрся в то, что есть ещё одна сущность, которую я сделал частью нескольких агрегатов одного типа...

А если учесть, что эта сущность в перспективе будет контрибьютить в инварианты этого типа агрегатов - Проект Р, кажись, не у ЭП, а у ДДД трубу зашатал...

#project_r@ergonomic_code #ddd@ergonomic_code #ergo_persistance@ergonomic_code #spring_data_jdbc@ergonomic_code
😱4👍1
Привет!

Прочитал субстак про Radical Object-Orientation (автор его ещё дописывает)

Имхо - Эргономичная архитектура, только в профиль.

- PoMO - очень напоминает то, что у меня ресурс может быть включен только в один другой ресурс
- IOSP - очень напоминает сбалансированную форму системы
- У него тоже дизайн рекурсивен - атомарная операция ио с точки зрения оркестрации сама может оказаться оркестрацией на своём уровне абстракции
- Так же придерживатеся мнения, что абстракция != public interface - "Integrations are abstractions as well."
- Но у автора всё, включая интеграции - есть объект. У меня, по крайней мере синтаксически, объектами (штуками эксклюзивно владеющими собственными состоянием) являются только ресурсы, а операции - это скрипты которые заимствуют состояние ресурсов и тем самым разделяют его между собой. Но. Всё приложение в целом - можно считать объектом.

Из минусов:
- (Относительно) многа букаф и картинок и очень мало кода, а тот что есть - тривиальный и про консольные приложения
- Аналогия с клетками привлекательная, но не очень... Клетки действительно организуют очень крутые, сложные и адаптивные системы. Которые человечество за миллион человеко-часов понять не может - хотим ли мы поддерживать такие системы?
- А ещё я в #project_r@ergonomic_code опять (но теперь под другим углом) начал сталкиваться с тем, что инкапсуляция состояния плохо масштабируется, так как влечёт неограниченный рост поверхности АПИ ключевых/центральных/фундаментальных объектов-ресусров.

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

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

#project_r подходит к концу и я ищу для себя новый проект по разработке веб-приложения, веб-сервиса или бакэнда мобильного приложения на JVM-стеке (Kotlin, Java).

Могу собрать команду и сделать проект "под ключ", могу выстроить эффективный процесс разработки в существующей команде, могу писать код.

Рассматриваю варианты работы по договору с ИП, договору ГПХ и трудовому договору.

Если вам или кому из ваших знакомых нужен хорошо сделанный бакэнд - приходите в личку, пожалуйста:)

Буду благодарен за репост.
🔥9👍5
Привет!

Начинаю потихоньку собирать отзывы по #project_r.

Начал с простого - спросил у второго разработчика, которая раньше на Котлин не писала: "Какие у тебя впечатления от Котлина? Не появилось непреодолимого желания переехать на него?:)"

Ответ:
только положительные 😀
очень много рутиных вещей из джавы уже есть в готовых функциях, читаемость намного лучше, легче конструкции логические всякие городить)
А про переехать 🤔
Если бы меня отправили работать в микросервис на котлине, я бы точно фу не сказала, спокойно бы писала, как и на джаве)

Выделение моё.

В общем если пишите на Java и сомневаетесь нужен ли вам Kotlin - попробуйте:)

#retro@ergonomic_code #project_r@ergonomic_code #kotlin@ergonomic_code
👍7💯6
Привет!

Продолжаю ретроспективить #project_r@ergonomic_code.

Подбил Джиру, собрал немного статистики:
1. всего задач по проекту: 223 - сюда входят и задачи на разработку, и баги, и мусорные задачи и метазадачи
2. задач на разработку по бэку проекта Р: 65
3. багов в бэке проекта Р: 12
4. регрессий в бэке проекта Р: 4
5. всего задач на разработку по бэку основного сервиса: 23
6. всего багов в беке основного сервиса: 28
7. всего регрессий в беке основного сервиса: 3
8. моих задач на разработку по бэку основного проекта: 6
9. моих багов в бэке основного проекта: 5
10. моих регрессий в бэке основного проекта: 2

Это упражнение я проделал для того чтобы проверить тезис "Применение ЭП снижает количество ошибок" и я получил очередное свидетельство этому:
1. отношение задач к ошибкам в сервисе по ЭП: 16/65 = 0.25
2. отношение задач к ошибкам в сервисе не по ЭП: 31/23 = 1.35
3. отношение моих задач к ошибкам в сервисе не по ЭП: 7/6 = 1.17

Тут по цифрам вообще выходит, что багов в 4-5 раз меньше, но, имхо, стоит сделать скидку на мою предвзятость в анализе и не учтённые факторы и сделать более консервативный вывод, что ЭП снижает количество ошибок в 2-3 раза.

Вопрос в том, стоит ли оно того - как показал опрос, большинство разработчиков не видит проблем в ошибках.

По хорошему, чтобы ответить на него, надо как-то привязаться к срокам и деньгам, но в этом проекте сделать этого не получится:
1. наверное, стоит начать с того, что по срокам мы тотально зафейлились🥲 Но по моему мнению, любой другой подход дал бы тот же результат
2. у меня есть данные только по своим трудозатратам, а в проекте участвовали ещё два разработчика
3. нет референса, к которому можно было бы привязаться.

#retro@ergonomic_code #project_r@ergonomic_code #case@ergonomic_code
🔥5👍4
Привет!

Что-то последняя большая новость никак не дозреет, поэтому пока расскажу о двух созревших.

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

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

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

Но сразу хочу предупредить, что ревью будет дотошное и каждый МР скорее всего будет проходить 2-3+ итерации ревью.
И что делать надо будет не только бэк, но и фронт. Как минимум вёрстку на Twitter Bootstrap (с чем неплохо чат-боты справляются) и, иногда UI-логику на AlpineJS типа такой: 1, 2, 3, 4.
В целом сейчас разбивка строк кода по типам следующая: Kotlin - 81%, html - 14%, css - 3%, js - 2%
Но фронт я ревьювлю уже не так дотошно. Думаю, если вы нагенеряете код гопатычем и он будет работать - я не замечу:)

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

И быстрого прогресса по книге не ожидайте - она будет бороться за мой ограниченный временной бюджет ещё и с ТА, блогом (где у меня план таки дописать пост про SQL в ближайшие пару недель, а потом таки написать ретро #project_r) и двумя детьми.

Кроме того, я под книгу планирую написать отдельную версию ТА, чтобы:
1. коммиты были привязаны к главам
2. API сделать в виде более распространённого JSON over HTTP, а не Тру REST API
3. в целом убрать исторические наслоения и быстрые хаки в коде, чтобы код был образцово-показательным, а не реальным в части компромиссов.

В общем, интуитивно, с учётом всех вводных мне кажется, что писать книгу я буду ещё года 2-3.

Так что стей тюнед, будет интересно:)

А ну и с третьей новостью - там тоже будет интересно (я мастер интриги 😂) - надеюсь в начале июня она таки дозреет:)

#trainer_advisor@ergonomic_code #ergo_book@ergonomic_code
👍17🔥32
Эргономичный код
Привет! С подачи Романа Русакова запоем прочитал The API. Очень крутая книга, рекомендую. Роман - спасибо:) Так же вы, возможно, задаётесь вопросом что это я затих. Вряд ли, конечно, но я всё равно отвечу - лопачу джиру Проект Э:) Чтобы понять стоило ли…
Привет!

Я тут недавно прочитал Overengineering in Onion/Hexagonal Architectures (перевод).

В целом с посылом поста я согласен (кроме мёржа REST-аннотаций в сервисы, хотя сам об этом думал), но там ничего суперкрутого - этот мой пост не про тот пост:)
А про собственную... Глу... человечность, назовём это так:)

В посте по ссылке есть тезис:

To put it another way, it is a design goal of the Application Service to host orchestration logic to allow lower-level components to become less coupled to one another.



Другими словами, Application Services предназначены для размещения логики оркестрации, что позволяет компонентам более низкого уровня быть менее связанными друг с другом.


Но я в 22-ом году (на 18-ом году коммерческой практики и примерно 5-ом году знания про Чистую архитектуру, ДДД, оркестрацию и сервисы приложений) всё равно изобрёл объектно-ориентированную декомпозицию. И пошёл делать по ней #project_e. И получил ровно, то, чего позволяют избегать сервисы приложений - высокую связанность между модулями-объектами.

Сколько ещё у меня таких "изобретений" из-за того что "смотрю в книгу, вижу фигу"? Вопрос риторический, конечно. Время покажет, всё что покажет - расскажу как на духу. Сегодня начал писать пост с ретро #project_r

PS>
И в топик "простых" CRUD приложений из комментов ко вчерашнему посту: в Overengineering in Onion/Hexagonal Architectures про них тоже тоже есть:

Like any tool, concentric architectures are not suitable for any software project. If the domain complexity of your problem is fairly low (CRUD-like), or if the challenge of your application is NOT in the complexity of its business rules, then the Onion/Hexagonal/Ports-Adapters/Clean Architecture might not be the best choice, and you might be better off with vertical slicing, anemic model, CQRS, or another type of architecture.



Как и любой другой инструмент, концентрическая архитектура подходит не для всех проектов. Если сложность предметной области вашей задачи довольно низкая (CRUDо-подобная) или если сложность вашего приложения заключается не в сложности его бизнес-правил, то архитектура Onion/Hexagonal/Ports-Adapters/Clean может оказаться не лучшим выбором, и вам, возможно, лучше использовать вертикальную архитектуру, анемичную модель, CQRS или другой тип архитектуры.


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

Третья большая новость наконец дозрела - я утряс все формальности и возобновил работу над Проектом Э!

Пока я пилил #project_r@ergonomic_code, заказчик пилил новый девайс, который делает замеры постоянно. И после его внедрения, нагрузка поднимется с ~3 измерений на пользователя в день до ~700.
А в самом оптимистичном сценарии - дорастёт до 50 RPS. Это ещё не хайлоад, конечно, но уже достаточно серьёзная нагрузка, которая не простит откровенно неэффективных решений.

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

И на мой взгляд, это очень крутая новость для ЭП. Это значит, что у меня будет реальная обратная связь из первых рук о том, как ЭП масштабируется и по размеру проекта (сейчас - 40k строк Котлин-кода и 72 таблицы) и по RPS.

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

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

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

Потому что во-вторых - в тестах произошла тотальная катастрофа. Там образовался дикий клубок зависимостей, который я распутывал и распиливал неделю. Наверное, тесты надо покрывать ArchUnit-тестами тоже:)

В общем если вы делаете модульный монолит, и хотите иметь возможность быстро выносить модули в отдельные сервисы - не лениесь как я и заводите для них сразу отдельные модули

#project_e@ergonomic_code #ergo_approach@ergonomic_code
🔥2