Всем привет!
Прочитал сегодня хороший пост (английский): https://korshakov.com/posts/death-of-best-practices
Чем же он хорош?
Иллюстрирует 2 мысли, про которые я топлю в своем блоге (и топлю в целом):
1) разработка - искусство компромиссов. Важно не абсолютное следование ... микросервисной архитектуре, принципам Single Responsibility или Dependency Inversion. Нет никакой магии в цифре 80% когда мы говорим о покрытии кода тестами. Денормализация таблиц из той же оперы. Важно выдавать результат, требуемый бизнесов. На код-ревью можно поспорить о принципах, но Pull Request должен быть влит в течение дня
2) быстрые, а следовательно частые релизы - наше все. Или по-менеджерски - Deployment Frequency и Lead Time (а это две грани одной и той же идеи). Это позволяет быстро править баги и уязвимости, адаптироваться к изменениям архитектуры и нормативным требованиям, проводить бета и A\B тестирование, соблюдать сроки выхода фичей.
Что спорно в посте - кликбейтный заголовок. Читать "Чистый код" или "Мифический человеко-месяц" - это не зло. Зло - следовать догматически отдельным идеям из этих книг, не разбираясь, что хотел сказать автор, и не адаптируя их к текущему проекту.
P.S. Тоже что ли кликбейтные заголовки начать делать)
#principles #dev_compomisses
Прочитал сегодня хороший пост (английский): https://korshakov.com/posts/death-of-best-practices
Чем же он хорош?
Иллюстрирует 2 мысли, про которые я топлю в своем блоге (и топлю в целом):
1) разработка - искусство компромиссов. Важно не абсолютное следование ... микросервисной архитектуре, принципам Single Responsibility или Dependency Inversion. Нет никакой магии в цифре 80% когда мы говорим о покрытии кода тестами. Денормализация таблиц из той же оперы. Важно выдавать результат, требуемый бизнесов. На код-ревью можно поспорить о принципах, но Pull Request должен быть влит в течение дня
2) быстрые, а следовательно частые релизы - наше все. Или по-менеджерски - Deployment Frequency и Lead Time (а это две грани одной и той же идеи). Это позволяет быстро править баги и уязвимости, адаптироваться к изменениям архитектуры и нормативным требованиям, проводить бета и A\B тестирование, соблюдать сроки выхода фичей.
Что спорно в посте - кликбейтный заголовок. Читать "Чистый код" или "Мифический человеко-месяц" - это не зло. Зло - следовать догматически отдельным идеям из этих книг, не разбираясь, что хотел сказать автор, и не адаптируя их к текущему проекту.
P.S. Тоже что ли кликбейтные заголовки начать делать)
#principles #dev_compomisses
Chaotic good engineering
Death of Best Practices
And why "clean code" is not the best way to build
Должен ли код быть сложным?
Для ответа на данный вопрос предлагаю разделить сложность кода на 2 категории - естественная и, соответственно, искусственная.
Естественная сложность кода будет всегда, т.к. причина ее появления - сложность предметной области. Это может быть сложная логика бизнес-процесса. Или возьмем Spring Core - там достаточно сложный жизненный цикл бинов, множество способов описания этих бинов, способов конфигурации, профили.... Я уже не говорю про JDK: модель байт-кода, компиляция, виртуальная машина, classloading, верификация байт-кода, JIT и оптимизации\отмена оптимизаций, сборка мусора, модель памяти, многопоточка и синхронизация доступа, поддержка различных архитектур процессора и ОС, отладка, профилирование, версионирование и обратная совместимость...
Есть понятные пути борьбы с естественной сложностью - микросервисы, слоистая архитектура, DDD и собственно объектно-ориентированное проектирование. Особенность этой сложности - она будет всегда.
Чего быть не должно - так это искусственной сложности. Причем тут бы я снова выделил две подкатегории:
1) то, на что указывают такие штуки как "большой ком грязи" или "божественный класс". Т.е. когда логика выполнения запутана потому, что за этим перестали следить. Или, в худшем случае, изначально не уделяли внимания проектированию. Усугубляет ситуацию здесь отсутствие базовой документации или ее неактуальность, огромное число ненужных настроек, плохой нейминг. Особенность этой категории сложности - вряд ли кто-то, кто увидит такой код, будет его хвалить. Все признают проблему, в т.ч. авторы. Решение - рефакторинг или переписывание кода с нуля.
2) искусственная сложность, сделанная с соблюдением принципов SOLID, ООП и слоистой архитектуры. Типичный пример здесь: микросервис с минимумом бизнес-логики, который можно сделать с использованием паттерна Transaction Script, но вместо этого появляется 3+ слоя, доменная модель, куча интерфейсов с одной реализацией, цепочка из вызовов сервисов, каждый из которых отвечает за одну функциональность по SOLID - авторизация, валидация, маппер, мониторинг, аудит, инициализация сетевых параметров, еще маппер, интеграционные логи, Circuit Breaker... Вроде все по правилам, а из простого сервиса сделан монстр, разобраться в котором очень сложно. Хотя на самом деле - правила нарушается. Как минимум правило KISS - Keep It Simple Stupid. Как максимум - не надо в том же Single Responsibility из SOLID идти до конца и для каждой функциональности, занимающей одну строчку код, делать класс. Как минимум делать это прямо сейчас. У нас же архитектура в коде. Код можно менять. В отличие от архитектуры здания, например. А разработка - это искусство компромиссов. Ну а главная проблема этой категории сложности - авторы кода точно ее не признают. Раз пишут такой код)
Итого - с любой сложностью можно и нужно бороться. Но особенно вредна искусственная сложность. По определению)
#arch #solid #complexity #principles #dev_compomisses
Для ответа на данный вопрос предлагаю разделить сложность кода на 2 категории - естественная и, соответственно, искусственная.
Естественная сложность кода будет всегда, т.к. причина ее появления - сложность предметной области. Это может быть сложная логика бизнес-процесса. Или возьмем Spring Core - там достаточно сложный жизненный цикл бинов, множество способов описания этих бинов, способов конфигурации, профили.... Я уже не говорю про JDK: модель байт-кода, компиляция, виртуальная машина, classloading, верификация байт-кода, JIT и оптимизации\отмена оптимизаций, сборка мусора, модель памяти, многопоточка и синхронизация доступа, поддержка различных архитектур процессора и ОС, отладка, профилирование, версионирование и обратная совместимость...
Есть понятные пути борьбы с естественной сложностью - микросервисы, слоистая архитектура, DDD и собственно объектно-ориентированное проектирование. Особенность этой сложности - она будет всегда.
Чего быть не должно - так это искусственной сложности. Причем тут бы я снова выделил две подкатегории:
1) то, на что указывают такие штуки как "большой ком грязи" или "божественный класс". Т.е. когда логика выполнения запутана потому, что за этим перестали следить. Или, в худшем случае, изначально не уделяли внимания проектированию. Усугубляет ситуацию здесь отсутствие базовой документации или ее неактуальность, огромное число ненужных настроек, плохой нейминг. Особенность этой категории сложности - вряд ли кто-то, кто увидит такой код, будет его хвалить. Все признают проблему, в т.ч. авторы. Решение - рефакторинг или переписывание кода с нуля.
2) искусственная сложность, сделанная с соблюдением принципов SOLID, ООП и слоистой архитектуры. Типичный пример здесь: микросервис с минимумом бизнес-логики, который можно сделать с использованием паттерна Transaction Script, но вместо этого появляется 3+ слоя, доменная модель, куча интерфейсов с одной реализацией, цепочка из вызовов сервисов, каждый из которых отвечает за одну функциональность по SOLID - авторизация, валидация, маппер, мониторинг, аудит, инициализация сетевых параметров, еще маппер, интеграционные логи, Circuit Breaker... Вроде все по правилам, а из простого сервиса сделан монстр, разобраться в котором очень сложно. Хотя на самом деле - правила нарушается. Как минимум правило KISS - Keep It Simple Stupid. Как максимум - не надо в том же Single Responsibility из SOLID идти до конца и для каждой функциональности, занимающей одну строчку код, делать класс. Как минимум делать это прямо сейчас. У нас же архитектура в коде. Код можно менять. В отличие от архитектуры здания, например. А разработка - это искусство компромиссов. Ну а главная проблема этой категории сложности - авторы кода точно ее не признают. Раз пишут такой код)
Итого - с любой сложностью можно и нужно бороться. Но особенно вредна искусственная сложность. По определению)
#arch #solid #complexity #principles #dev_compomisses