Всем привет!
Я уже подымал тему готовых архитектурных решений, а точнее их отсутствия в большинстве случаев https://t.me/javaKotlinDevOps/134
Хочу развернуть тему с другой стороны.
Стоит ли тратить силы на поиск целевого архитектурного решения?
Написал эту фразу, и понял, что не всем она может быть понятна) Расшифрую. В больших компаниях ака "кровавый enterprise" есть некий список разрешенных технологий и архитектурных принципов. Оформленный в виде техрадара, карты технологических стеков и сборника архитектурных стандартов. Это и есть целевая архитектура.
Так вот, беда с этим стандартами одна - со временем их становится слишком много, понять - как сделать правильно, чтобы работало годами без переделки - сложно. Нужно на это тратить время: для того, чтобы обойти всех заинтересованных архитекторов, смежные команды, и выработать целевое решение.
Так вот - а надо ли его искать? Несмотря на то, что ответ вроде бы очевиден, хотел бы подсветить несколько потенциальных проблем.
Затрачивая время на поиск и согласование целевого решения мы взамен хотим получить уверенность, что решение с нами останется "на века". Так ли это? Нет, не так. Во-первых мир меняется очень сильно, бизнес задачи меняются вместе с ним. Во-вторых технологии меняются еще сильнее. В-третьих - "кассандр" среди нас мало, и если есть несколько разрешенных технологий - угадать правильную сложно.
К чему это приводит? Мы потратили время на выбор и реализацию "целевки", а через год нам говорят - переделывайте. Отрицание, гнев, фрустрация. Обида на архитекторов. Причем даже если архитектор признает ошибку (и вообще эта ошибка была) - вряд ли он поможет переписать код. Обида на менеджеров - да они издеваются что ли, вечно меняют правила игры, вечная миграция... Желание сменить компанию...
Поэтому видится, что есть более надежный подход.
1) смириться с тем, что все течет, все меняется, и миграции будут всегда
2) искать целевые решение, но всегда держать в уме, что это целевое решение на данный момент
3) разделить весь код на ядро и инфраструктурный код. Ядро стараться писать на чистой Java \ Kotlin, с минимальным использованием фреймворков. Особенно, внутренних, которые еще не доказали свою стабильность. Внешние интеграции закрывать - предохранительный слой (anticorruption layer), шлюзы (gateway), адаптеры.
4) очень важно - уметь и хотеть быстро выпускать релизы, разбивать любые доработки на небольшие инкременты. Это можно сделать как улучшением качества проектирования, увеличением покрытия тестами и автотестами, так и различного рода договоренностями со смежниками, (не забываем, что мы в "кровавом enterprise")
Если вам показывался знакомым последний пункт - то да, это Agile. Или то самое снижение Lead Time (LT), о котором любят говорить менеджеры. И не только говорить) Но в данном случае они правы.
Еще пример - фондовый рынок и диверсификация. Диверсификация считается основным принципом разумного инвестора, и означает, что нельзя "класть все яйца в одну корзину". Т.е. нужно покупать разные классы активов: акции, облигации, вклады, кэш, золото, недвижимость. Причина - сложно угадать, что именно "выстрелит". В случае кода сложно конечно реализовать диверсификацию прямолинейно: часть данных хранить в PostgreSQL, а часть - в Oracle. Да и не нужно. Но предусмотреть возможность замены поставщика - нужно.
#agile #arch #arch_compromisses
Я уже подымал тему готовых архитектурных решений, а точнее их отсутствия в большинстве случаев https://t.me/javaKotlinDevOps/134
Хочу развернуть тему с другой стороны.
Стоит ли тратить силы на поиск целевого архитектурного решения?
Написал эту фразу, и понял, что не всем она может быть понятна) Расшифрую. В больших компаниях ака "кровавый enterprise" есть некий список разрешенных технологий и архитектурных принципов. Оформленный в виде техрадара, карты технологических стеков и сборника архитектурных стандартов. Это и есть целевая архитектура.
Так вот, беда с этим стандартами одна - со временем их становится слишком много, понять - как сделать правильно, чтобы работало годами без переделки - сложно. Нужно на это тратить время: для того, чтобы обойти всех заинтересованных архитекторов, смежные команды, и выработать целевое решение.
Так вот - а надо ли его искать? Несмотря на то, что ответ вроде бы очевиден, хотел бы подсветить несколько потенциальных проблем.
Затрачивая время на поиск и согласование целевого решения мы взамен хотим получить уверенность, что решение с нами останется "на века". Так ли это? Нет, не так. Во-первых мир меняется очень сильно, бизнес задачи меняются вместе с ним. Во-вторых технологии меняются еще сильнее. В-третьих - "кассандр" среди нас мало, и если есть несколько разрешенных технологий - угадать правильную сложно.
К чему это приводит? Мы потратили время на выбор и реализацию "целевки", а через год нам говорят - переделывайте. Отрицание, гнев, фрустрация. Обида на архитекторов. Причем даже если архитектор признает ошибку (и вообще эта ошибка была) - вряд ли он поможет переписать код. Обида на менеджеров - да они издеваются что ли, вечно меняют правила игры, вечная миграция... Желание сменить компанию...
Поэтому видится, что есть более надежный подход.
1) смириться с тем, что все течет, все меняется, и миграции будут всегда
2) искать целевые решение, но всегда держать в уме, что это целевое решение на данный момент
3) разделить весь код на ядро и инфраструктурный код. Ядро стараться писать на чистой Java \ Kotlin, с минимальным использованием фреймворков. Особенно, внутренних, которые еще не доказали свою стабильность. Внешние интеграции закрывать - предохранительный слой (anticorruption layer), шлюзы (gateway), адаптеры.
4) очень важно - уметь и хотеть быстро выпускать релизы, разбивать любые доработки на небольшие инкременты. Это можно сделать как улучшением качества проектирования, увеличением покрытия тестами и автотестами, так и различного рода договоренностями со смежниками, (не забываем, что мы в "кровавом enterprise")
Если вам показывался знакомым последний пункт - то да, это Agile. Или то самое снижение Lead Time (LT), о котором любят говорить менеджеры. И не только говорить) Но в данном случае они правы.
Еще пример - фондовый рынок и диверсификация. Диверсификация считается основным принципом разумного инвестора, и означает, что нельзя "класть все яйца в одну корзину". Т.е. нужно покупать разные классы активов: акции, облигации, вклады, кэш, золото, недвижимость. Причина - сложно угадать, что именно "выстрелит". В случае кода сложно конечно реализовать диверсификацию прямолинейно: часть данных хранить в PostgreSQL, а часть - в Oracle. Да и не нужно. Но предусмотреть возможность замены поставщика - нужно.
#agile #arch #arch_compromisses
Telegram
(java || kotlin) && devOps
Всем привет!
Выпил бокал пива и захотелось немного пофилософствовать)
У меня часть просят готовое решение какой-то проблемы. Это может быть способ интеграции, выбор места для хранения данных, языка программирования, способ разбиения проекта на микросервисы…
Выпил бокал пива и захотелось немного пофилософствовать)
У меня часть просят готовое решение какой-то проблемы. Это может быть способ интеграции, выбор места для хранения данных, языка программирования, способ разбиения проекта на микросервисы…
👍2
Качественное ли у вас API? А чем докажете?)
Как мы проверяем код на качество? SonarQube, покрытие кода тестами. Если говорить о code style - CheckStyle-ом. Если говорить об уязвимостях - проверка по базам уязвимостей (разные тулы), Checkmarx.
А можно ли как-то проверить API на соответствие лучшим практикам? В частности, OpenAPI как самый типовой на данный момент вариант.
Да - для этого есть Spectral linter https://meta.stoplight.io/docs/spectral/a630feff97e3a-concepts
У него три основных достоинства:
1) это linter и его можно включить в CI pipeline
2) у него есть наборы предустановленных правил, в частности:
а) OpenAPI rules https://meta.stoplight.io/docs/spectral/4dec24461f3af-open-api-rules
б) URL rules https://apistylebook.stoplight.io/docs/url-guidelines - использование kebab-case, не использование get в URL...
в) OWASP rules https://apistylebook.stoplight.io/docs/owasp-top-10 - безопасность, например, использование uuid вместо чисел в идентификаторах
...
3) возможность добавлять свои правила https://meta.stoplight.io/docs/spectral/01baf06bdd05a-create-a-ruleset в том числе наследуясь от существующих
Ну и отдельно отмечу, что есть плагин для IDEA https://plugins.jetbrains.com/plugin/25989-spectral-linter
Итого - штука полезная, настоятельно рекомендую попробовать.
#api #arch #code_quality
Как мы проверяем код на качество? SonarQube, покрытие кода тестами. Если говорить о code style - CheckStyle-ом. Если говорить об уязвимостях - проверка по базам уязвимостей (разные тулы), Checkmarx.
А можно ли как-то проверить API на соответствие лучшим практикам? В частности, OpenAPI как самый типовой на данный момент вариант.
Да - для этого есть Spectral linter https://meta.stoplight.io/docs/spectral/a630feff97e3a-concepts
У него три основных достоинства:
1) это linter и его можно включить в CI pipeline
2) у него есть наборы предустановленных правил, в частности:
а) OpenAPI rules https://meta.stoplight.io/docs/spectral/4dec24461f3af-open-api-rules
б) URL rules https://apistylebook.stoplight.io/docs/url-guidelines - использование kebab-case, не использование get в URL...
в) OWASP rules https://apistylebook.stoplight.io/docs/owasp-top-10 - безопасность, например, использование uuid вместо чисел в идентификаторах
...
3) возможность добавлять свои правила https://meta.stoplight.io/docs/spectral/01baf06bdd05a-create-a-ruleset в том числе наследуясь от существующих
Ну и отдельно отмечу, что есть плагин для IDEA https://plugins.jetbrains.com/plugin/25989-spectral-linter
Итого - штука полезная, настоятельно рекомендую попробовать.
#api #arch #code_quality
docs.stoplight.io
Concepts | Spectral
The power of integrating linting into the design-first workflow, or any workflow which involves API descriptions, is often overlooked. Linting isn't just about validating OpenAPI or JSON Schema documents against specifications. It's for enforcing ... Powered…
Должен ли код быть сложным?
Для ответа на данный вопрос предлагаю разделить сложность кода на 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