Чистая архитектура прекрасно сочетается с языком Go — вы не найдёте принципов, которые бы противоречили style guide языка или его философии.
Проблема, прежде всего, в самих инженерах. Автор и множество комментаторов, судя по их высказываниям, вовсе не понимают, что такое чистая архитектура. Для них DRY, KISS и SOLID — это одно и то же. Со стороны выглядит как: "ничего не понял, но на всякий случай осуждаю".
Между SOLID и YAGNI столько же общего, сколько между SOLID и ОМОН — их объединяет только то, что это аббревиатуры. Подскажите, вы действительно считаете, что фраза "вам это не понадобится" и вполне конкретный принцип инверсии зависимостей — это ровно одно и то же?
Чистая архитектура хорошо согласуется с возможностями языка Go и не противоречит его философии. Проблема заключается в низком уровне инженерной культуры у части разработчиков, которые не в состоянии освоить принципы SOLID, что порождает их отторжение.
Например, очень часто можно встретить мнение, что принцип подстановки Барбары Лисков (LSP) не применим к Go из-за отсутствия наследования, но это не так.
Интересная статья, но чувствуется, что взгляд на архитектуру сформировался в среде, где энтерпрайз-подходы не понимают в принципе.
В целом, автор прав: если в команде нет общего понимания архитектуры, проект будет страдать. Но проблема не в том, что архитектурные подходы плохи, а в том, что их часто неправильно понимают или применяют без должного контекста. А чтобы это исправить, нужно не только писать правила, но и повышать общую культуру проектирования в команде.
К сожалению, в русскоязычном Go-сообществе действительно очень слабо с пониманием SOLID и чистой архитектуры в частности. Вместо того чтобы разобраться, как это работает, многие разработчики просто уходят в отрицание и заявляют, что им это не нужно, хотя на самом деле, скорее всего, просто стесняются признаться, что не смогли разобраться.
YAGNI упомянут совершенно не к месту. Это не «принцип, который почему-то большинство игнорирует», а скорее философская установка, которая формально «за всё хорошее и против всего плохого», но при этом не даёт никаких конкретных границ или ограничений, в отличии от реальных принципов
Без них работать не будет, но сегодня любая система контейнеризации де-факто стандарт, поэтому мне кажется здесь можно позволить себе удобство.
Ну docker это не единственная система контейнеризации и даже не самая популярная, в большинстве оркестраторов докер runtime уже давно не используют. Помимо этого у докера очень неприятная лицензия для коммерческого использования.
Да, действительно контейнеризация это стандарт. Если testcontainer не умеет работать с альтернативными runtime – это проблема.
А костыль в чем? В том что ты привязываешься к контейнеризации?
В моём понимании тесты должны проверять логику, а не разворачивать инфраструктуру. Реальные проблемы продакшена (репликация, сетевые задержки, разные версии СУБД) в тестовом контейнере не воспроизводятся, хотя в CI это более чем реально реализовать.
А если нет докера, podman или colima, это тоже работать будет?
Мы тем самым избавляемся от необходимости думать какой сервис нам надо поднять, нам нужно просто запустить тесты
Ну не звучит, как большая когнитивная нагрузка. Я не уверен, что ради этого нужно костылить в тестах, т.к. это же принесёт дополнительные проблемы
в ci не надо делать отдельно up и down контейнеров с тестовой инфрой
Ну тоже как будто не очень сложно, но решает проблему когда у нас в качестве раннера используется докер контейнеры. Насколько я помню, там у testcontainer есть какие-то проблемы с dind
Я потом наследуюсь от протокола вот тут. Это нужно для того, чтобы быть уверенным, что какой-то класс удовлетворяет протоколу. Когда у вас много протоколов и объектов которые имплементируют их, то такое поведение очень удобно
На самом деле у нас pydantic то и не было, у нас была своё самописная библиотека для этих целей. Просто поддерживать её не представляется возможным.
Если выделить, чем нам pydantic не нравится, то: - Не позволяет создавать один и тот же класс из нескольких источников или отдавать в разном виде. - При создании модели вручную, нужно передавать поля по алиасам, allow_population_by_name не решает эту проблему. - Неявные преобразование типов - По мелочи какое-то неявное поведение
Ну если говорить о том, чем он лучше FastAPI, то тут можно выделить несколько моментов: 1. Гвоздями не прибит pydantic 2. Есть ClassView (мне нравится) 3. Depends от FastAPI отражается в OpenAPI схеме, в Litestar - нет
На прод только планируем затаскивать для одного из сервисов. Единственное, что вместо pydantic планируем использовать msgspec.
Из неочевидных особенностей хочу отметить, что тащить все батарейки из Litestar к себе в проект не стоит, лучше ограничиться только функционалом http фреймворка.
Чистая архитектура прекрасно сочетается с языком Go — вы не найдёте принципов, которые бы противоречили style guide языка или его философии.
Проблема, прежде всего, в самих инженерах. Автор и множество комментаторов, судя по их высказываниям, вовсе не понимают, что такое чистая архитектура. Для них DRY, KISS и SOLID — это одно и то же. Со стороны выглядит как: "ничего не понял, но на всякий случай осуждаю".
Между SOLID и YAGNI столько же общего, сколько между SOLID и ОМОН — их объединяет только то, что это аббревиатуры. Подскажите, вы действительно считаете, что фраза "вам это не понадобится" и вполне конкретный принцип инверсии зависимостей — это ровно одно и то же?
Чистая архитектура хорошо согласуется с возможностями языка Go и не противоречит его философии. Проблема заключается в низком уровне инженерной культуры у части разработчиков, которые не в состоянии освоить принципы SOLID, что порождает их отторжение.
Например, очень часто можно встретить мнение, что принцип подстановки Барбары Лисков (LSP) не применим к Go из-за отсутствия наследования, но это не так.
Интересная статья, но чувствуется, что взгляд на архитектуру сформировался в среде, где энтерпрайз-подходы не понимают в принципе.
В целом, автор прав: если в команде нет общего понимания архитектуры, проект будет страдать. Но проблема не в том, что архитектурные подходы плохи, а в том, что их часто неправильно понимают или применяют без должного контекста. А чтобы это исправить, нужно не только писать правила, но и повышать общую культуру проектирования в команде.
К сожалению, в русскоязычном Go-сообществе действительно очень слабо с пониманием SOLID и чистой архитектуры в частности. Вместо того чтобы разобраться, как это работает, многие разработчики просто уходят в отрицание и заявляют, что им это не нужно, хотя на самом деле, скорее всего, просто стесняются признаться, что не смогли разобраться.
YAGNI упомянут совершенно не к месту. Это не «принцип, который почему-то большинство игнорирует», а скорее философская установка, которая формально «за всё хорошее и против всего плохого», но при этом не даёт никаких конкретных границ или ограничений, в отличии от реальных принципов
Да, ты абсолютно прав. Хорошей практикой будет писать сервисные тесты для юзкейсов (необязательно только для happy path)
Приложение тоже не контролирует инфру и никаких проблем нет, чем тесты отличаются от основного приложения в этом контексте?
Так я же не говорю, что тестам нужно отрезать инфраструктуру. Я просто считаю, что не нужно тесты и инфру смешивать.
Инфраструктура разворачивается отдельно от тестов, тесты её используют
Ну docker это не единственная система контейнеризации и даже не самая популярная, в большинстве оркестраторов докер runtime уже давно не используют. Помимо этого у докера очень неприятная лицензия для коммерческого использования.
Да, действительно контейнеризация это стандарт. Если testcontainer не умеет работать с альтернативными runtime – это проблема.
В моём понимании тесты должны проверять логику, а не разворачивать инфраструктуру. Реальные проблемы продакшена (репликация, сетевые задержки, разные версии СУБД) в тестовом контейнере не воспроизводятся, хотя в CI это более чем реально реализовать.
Мне наоборот кажется, что моки проще для демонстрации концепции, т.к. для них нужно меньше кода писать.
Но с выводами согласен, стабы действительно обладают некоторыми преимуществами над mock-объектами
А если нет докера, podman или colima, это тоже работать будет?
Ну не звучит, как большая когнитивная нагрузка. Я не уверен, что ради этого нужно костылить в тестах, т.к. это же принесёт дополнительные проблемы
Ну тоже как будто не очень сложно, но решает проблему когда у нас в качестве раннера используется докер контейнеры. Насколько я помню, там у testcontainer есть какие-то проблемы с dind
Слушай, ну так у тебя уже есть база данных для того, чтобы локально вести разработку. Зачем в таком случае использовать testcontainers?
Я потом наследуюсь от протокола вот тут.
Это нужно для того, чтобы быть уверенным, что какой-то класс удовлетворяет протоколу.
Когда у вас много протоколов и объектов которые имплементируют их, то такое поведение очень удобно
PEP 544
На самом деле у нас pydantic то и не было, у нас была своё самописная библиотека для этих целей. Просто поддерживать её не представляется возможным.
Если выделить, чем нам pydantic не нравится, то:
- Не позволяет создавать один и тот же класс из нескольких источников или отдавать в разном виде.
- При создании модели вручную, нужно передавать поля по алиасам, allow_population_by_name не решает эту проблему.
- Неявные преобразование типов
- По мелочи какое-то неявное поведение
Ну если говорить о том, чем он лучше FastAPI, то тут можно выделить несколько моментов:
1. Гвоздями не прибит pydantic
2. Есть ClassView (мне нравится)
3. Depends от FastAPI отражается в OpenAPI схеме, в Litestar - нет
На прод только планируем затаскивать для одного из сервисов.
Единственное, что вместо pydantic планируем использовать msgspec.
Из неочевидных особенностей хочу отметить, что тащить все батарейки из Litestar к себе в проект не стоит, лучше ограничиться только функционалом http фреймворка.