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

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

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

Утренние мысли.

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

решил попробовать чутка сдать позиции, и пустить spring data jdbc в слой домена, и спринг в целом в слой приложения/юз кейсов/интеракторов. На этом фоне, внезапно подумал, что надо поглядедь на код анкл Боба - может всё-таки без этого можно обойтись и всё придумано до нас.

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

Тогда я решил залезть в репоз 8th light (которы вроде бы связанной с анкл Бобом). Там тоже всякая мелочёвка.

Дальше я пошёл просто шукать по гитхабу Clean Architecture. Тут уже появились демо проектики с одной сущностью. Но всё ещё ни одного реального репоза с проектом хотя бы на 5-10 сущностей.

Писать посты и рисовать красивые картинки легко - сам так делаю:) Но “Talk is cheap. Show me the code.” (c) Torvalds.
Знаете хоть один живой пример проекта с чистой архитектурой?

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

Пойду дальше искать своего Грааля:)

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

Прочитал любопытную статью «Чистый» код, ужасная производительность.
Там мужик (автор оригинала) меряет урон от применения принципов чистого кода в деградации айфонов.
И в комментах его справедливо обвиняют в профдеформации.

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

Но самое любопытное, что в Чистом коде анкл Боб был более осторожен. Хотя в разделе "Switch Statements" он призывает "хоронить switch в низкоуровневых фабриках", далее в разделе "Data/Object Anti-Symmetry" он уже не так категоричен:

> Procedural code (code using data structures) makes it easy to add new functions without changing the existing data structures. OO code, on the other hand, makes it easy to add new classes without changing existing functions.

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

Поэтому я сейчас придерживаюсь эвристики, что для объектов, которые скорее представляют сервисы, я использую полиморфизм, а для объектов, которые скорее представляют данные - алгебраические типы данных (sealed классы и интерфейсы в Котлине и свежей Джаве).

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

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

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

Вообще, это всё хорошо известная и изученная Expression problem, для которой не существует (пока что) хорошего решения.

А и спасибо мужику за доп аргумент в пользу АДТ - скорее всего они ещё и работают быстрее. Хотя в случае JVM я бы за это не поручился без бенчей.

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

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

Лично меня больше всего порадовала мысль Андроид разработчика, что бэк - это не деталь реализации, а домен:)

Правда следуя этой логике, можно прийти и к тому, что БД - это не деталь реализации, а домен:)
Что, на самом-то деле, похоже на правду - я уже не раз выкидывал "ядро" системы в виде кода, оставляя "деталь реализации" в виде данных в текущей схеме и строил новое ядро поверх этой детали.

#posts@ergonomic_code #clean_architecture@ergonomic_code
🔥41
Привет!

Я в 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
И в догонку накопал жёский наборос
It is high time to ‘kill’ Clean Architecture, the Hex, the Onion and the VSA and come up with something better

One of the most common ‘architectures’ among aspiring software designers is either the Clean Spaghetti Architecture or the Hexagonal Bubble Architecture. I don’t blame them for using these antipatterns. At least they are trying something new. They are going out of their comfort zone, ready to make mistakes. Here is a visual representation of both these architectures

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

Но вот чтобы так жёска и прям с порога - это надо иметь смелость:)

PS> сам пост ещё не прочитал

#clean_architecture@ergonomic_code
Привет!

Мысли в слух.

Наткнулся на очередную свеженькую статью по чистой архитектуре.
В двух словах: чистая архитектура - это не про пакеты - не заводите пакеты domain, application, infrastructure, web, заводите пакеты по фичам.
В целом ничего супероригинального, но любопытный аргумент в пользу пакетирования по фичам там есть — по мере жизни приложения, у него появляются новые фичи, а новые слои — практически никогда.

И так как покой мне только снится, это меня натолкнуло на мысль о потенциальной эргономичной структуре программ в4. в3 выглядит так, напомню.
Сейчас она у меня в целом работает и серьёзных нареканий нет, но мне не нравится фактическое дублирование содержания пакетов app и core, в случае если app декомпозируется по фичам.

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

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

Или я что-то не понимаю, или в Чистой архитектуре есть дыра.

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

Во-вторых, у нас есть самый внешний слой фреймворков и драйверов, который "как правило, состоит из фреймворков и инструментов, таких как база данных и веб-фреймворк."

А в третьих, есть адаптеры интерфейсов, про которые анкл Боб пишет: "Никакой код, находящийся внутри этого круга, вообще ничего не должен знать о базе данных. Если база данных является базой данных SQL, то весь SQL должен быть ограничен этим уровнем и, в частности, теми частями этого уровня, которые имеют отношение к базе данных."

То есть, получается, что слой адаптеров должен знать про БД, которая находится уровнем выше и нарушать правило зависимостей?

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

#clean_architecture@ergonomic_code
🔥2🤔1🤯1
И к слову, про реальную обратную связь. И про то, что мне не дают покоя лавры анкл Боба:)

Наше исследование идёт своим чередом, и там между делом зашла речь про анкл Боба. В частности, что его идеи не ложатся на реальную практику. Я высказал предположение, что анкл Боб последние лет 20 не участвует в реальной разработке. А потом спросил у гопатыча, дипсика и алисы. Дипсик и алиса подтвердили, гопатыч соврал - сослался сюда и сказал что реальный опыт есть, но по ссылке ничего об этом не написано.

Короче, не слушайте анкл Боба, слушайте меня - у меня каждая идея выстрадана и опробована в коммерческой практике:)

#ergo_approach@ergonomic_code #solid@ergonomic_code #clean_architecture@ergonomic_code
7