Хочу отметить, что обычно используются data transfer objects (DTO) для передачи данных между слоями. Добавляя теги структуры (json, db) к domain сущностях мы связываем слои
Видео интересное но вот архитектура вызывает вопросы, мягко говоря. Разбитие файлов на папки по типам приводит к появлению нескольких помоек. Помойка 1 "package service" где хранятся куча несвязанных между собой сервисов, представьте себе, что всю логику стандартной библиотеки засунули в один пакет service. В результате любое обращение начиналось бы с service.{Какой-то метод}, это неудобно и является антипаттерном, это тоже самое что сделать пакет "utils" в который напихать всё что не знаем куда положить. Пакеты в го должны инкапсулировать определенную часть действий и предоставлять пользователю удобный интерфейс. Рекомендую посмотреть организацию stdlib, в котором всё разложено очень грамотно. Вторая помоечка получается в анемичных сущностях, представьте что их там не 10 штук, а 100, 200?! 500?!, будет ли удобно работать с таким проектов? И ещё, домен это не только тупые структурки. И, как уже отмечали, в ваши сущности протекла реализация БД, чего тоже быть не должно. Отдельно отмечу про тесты, если вы хотите иметь качественные тесты, пишите их до написания кода (red-green-refactor), а не после того как вы уже реализовали логику. Тесты должны помогать вам проектировать ваш проект, тесты являются первыми "пользователями" того кода, что вы пишите. В большинстве случаев, тесты написанные после, не слишком полезны и присутствуют для вида: "смотрите мы умеем тестировать" - нет, не умеете 😅 Закончу на позитивной ноте, такая архитектура позволяет разработчику не думать вообще, есть моделька клади к моделькам, есть какая-то логика - создавай сервис. А то, что там уже 100 сервисов и у каждого по 100 методов - "то таке" :)
На ютубе не видел ничего подобного, куча роликов по чистой архитектуре, но не с такой подробностью и объяснениями, спасибо Максим! Было бы еще круто прикрепить ссылку на гитхаб проект, если он не приват конечно
@@backendninja6737 Поэтому всегда нужно выкладывать учебные проекты с такой же структурой. Я либо создал бы отдельный для этого репозиторий на имеющемся гитхаб, либо создал новый аккаунт для учебных целей.
Всё выглядит здорово, только доменные сущности зависят от используемой базы данных, т.к. там прописаны нестандартные типы (NullStr, NullInt), а такого не должно быть. Доменный уровень не должен ничего знать о деталях реализации приложения.
23:14 если у нас есть пакет bank, который выполняет всю логику, то в папку cmd следовалы бы в начале добавить папку bank и лишь в неё класть main. Тогда бы и бинарник назвался сразу bank, и название проекта очевидно
Чел рассказывает про чистую архитектуру, не понимая ее смысл и все подряд за интерфейсы прячет. Смысл чистой архитектуры в том что бизнес-логика инкапсулирована и не зависит ни от чего и мы спокойно можем перекинуть любой домен с бизнес логикой на другой сервис и все взлетит. У тебя же бизнес логика зависит от того какой контракт использует транспортер, должно быть наоборот транспортер должен зависеть от того какие методы есть в классах с бизнес логикой
Спасибо, хорошо подал матерьял! Но есть предложение, раздели файл с миграциями, разложи сущности по отдельным файлам, пакет migration это позволяет делать)
Дублирование описания интерфейсов, это конечно лютая жесть. А советовать такое, жесть вдвойне. Сразу видно что у авторов кода нет опыта работы с плюсами, джавой и и.п. Действительно интерфейс описывается по месту использования, т.к. там мы не должны зависеть от реализации. Но что мешает вынести описание интерфейса в отдельный файл?!
Максим, добрый день) Спасибо за видео) Подскажи пожалуйста, а как бизнес логика реализует интерфейсы из транспортного уровня, на уровне языка? Плюс в виде говорилось, что у уровней односторонняя связь, а объявление интерфейсов для уровня бизнес логики в транспортном уровне приводит к двусторонней зависимости уровней?
Странно, бизнес-логику мы хотим выделить в сервисный слой, чтобы разные транспорты не дублировали код, а валидацию предлагается все еще в транспорте делать
Максим, спасибо за труды!!! Последние месяцы пытаюсь понять реализацию чистой архитектуры и уже встречал такое же мнение насчёт описания и реализации интерфейсов, в частности я говорю об отрывке с 17:35 . Но мне как человеку, у которого нет реальных проектов за плечами (только учебные) не совсем понятна терминология. Я прям сейчас сижу и пишу в тетрадку: "интерфейсы описываются не на том уровне, где реализуются, а на том уровне, где используются". Для такого обывателя как я, "реализуются" и "используются" звучат как синонимы (и я раньше это тоже слышал, но не понял до сих пор что это значит системно). Я вижу на экране у вас разницу в компоновке по пакетам, однако, может у вас получиться дать четкие определения "реализации" и "использования" интерфейсов? На видео вы подбирали слова, когда объясняли, возможно и вам будет легче объяснить разницу в подходах, после углубления в тему.
Есть два понятия: декларация(объявление) и реализация Декларация - это описание интерфейса, т.е. есть такая функция с такой сигнатурой Реализация - это сам код функции, которая соответствует объявленной сигнатуре. type Example interface { Do(value uint) int } type ExampleStruct struct {} func (es ExampleStruct) Do(value int) int { return value } В плане концепции, это смена "я тебе передам такой тип" на "я ожидаю такой тип"
Привет, у тебя интересный контент, убедительная просьба, поработай со своей речью. Читай художественную литературу вслух, работай у зеркала и тд. Спасибо за твой труд!
Я тоже над этим призадумался. Ведь, если абстрагироваться от Go, а взять язык, где необходимо конкретно указывать, какой интерфейс реализует структура. Получится, что некий репозиторий, полезет за интерфейсом на более высокий архитектурный слой, что быть получается не должно. А вот сервису, за интерфейсом репозитория, вниз спросить можно. Конкретно в Go, интерфейсы конечно реализуются не явно, но в душе все равно какое-то противоречие появляется.
Короче разобрался. Вопрос спорный, однако если у нас множество раз используется какой-либо контракт (интерфейс) в различных сервисах, то имеет смысл выносить их в отдельную папку(пакет) и уже использовать их оттуда
Давно за тобой слежу, подскажи пожалуйста: Возможно ли начать учиться по твоим курсам с полного нуля или же лучше начать с другого популярного языка (с какого?) и потом переключиться на Go?)
Хочу отметить, что обычно используются data transfer objects (DTO) для передачи данных между слоями. Добавляя теги структуры (json, db) к domain сущностях мы связываем слои
забей, чел выскочка) чисто инфоцыган
@@Alexandr234 а что читать/кого смотреть сам посоветуешь?
Лайк авансом!
То чувство, когда следующие 27 минут пройдут офигенно, спасибо!
Рад слышать 🙏🏻
Видео интересное но вот архитектура вызывает вопросы, мягко говоря.
Разбитие файлов на папки по типам приводит к появлению нескольких помоек. Помойка 1 "package service" где хранятся куча несвязанных между собой сервисов, представьте себе, что всю логику стандартной библиотеки засунули в один пакет service. В результате любое обращение начиналось бы с service.{Какой-то метод}, это неудобно и является антипаттерном, это тоже самое что сделать пакет "utils" в который напихать всё что не знаем куда положить.
Пакеты в го должны инкапсулировать определенную часть действий и предоставлять пользователю удобный интерфейс. Рекомендую посмотреть организацию stdlib, в котором всё разложено очень грамотно.
Вторая помоечка получается в анемичных сущностях, представьте что их там не 10 штук, а 100, 200?! 500?!, будет ли удобно работать с таким проектов? И ещё, домен это не только тупые структурки. И, как уже отмечали, в ваши сущности протекла реализация БД, чего тоже быть не должно.
Отдельно отмечу про тесты, если вы хотите иметь качественные тесты, пишите их до написания кода (red-green-refactor), а не после того как вы уже реализовали логику. Тесты должны помогать вам проектировать ваш проект, тесты являются первыми "пользователями" того кода, что вы пишите. В большинстве случаев, тесты написанные после, не слишком полезны и присутствуют для вида: "смотрите мы умеем тестировать" - нет, не умеете 😅
Закончу на позитивной ноте, такая архитектура позволяет разработчику не думать вообще, есть моделька клади к моделькам, есть какая-то логика - создавай сервис. А то, что там уже 100 сервисов и у каждого по 100 методов - "то таке" :)
На ютубе не видел ничего подобного, куча роликов по чистой архитектуре, но не с такой подробностью и объяснениями, спасибо Максим!
Было бы еще круто прикрепить ссылку на гитхаб проект, если он не приват конечно
Я бы поделился ссылкой, но это приватный коммерческий проект) Спасибо! 🙏🏻
@@backendninja6737 Поэтому всегда нужно выкладывать учебные проекты с такой же структурой. Я либо создал бы отдельный для этого репозиторий на имеющемся гитхаб, либо создал новый аккаунт для учебных целей.
Всё выглядит здорово, только доменные сущности зависят от используемой базы данных, т.к. там прописаны нестандартные типы (NullStr, NullInt), а такого не должно быть. Доменный уровень не должен ничего знать о деталях реализации приложения.
Давай чувак, топи дальше, мы как всегда с тобой!
Он теперь инфоциган. Потеряли пацана. 😢
Максим как всегда в своем репертуаре! Все супер, как и всегда!)
Спасибо 🙌
Спасибо большое за полезный видос. Все понятно и просто объяснил.
Ожидал увидеть архитектуру конкретно под го (микросевисы, все это вот), увидел обычные практики чистого кода для монолита
Спасибо за урок!
23:14 если у нас есть пакет bank, который выполняет всю логику, то в папку cmd следовалы бы в начале добавить папку bank и лишь в неё класть main. Тогда бы и бинарник назвался сразу bank, и название проекта очевидно
Бинарник можно назвать как угодно, при компиляции
@@magistr_sav иии?) я те про логику названия папок, а ты мне про возможности языка. Не используй вообще функционал, пиши плейн код.
Наконец-то вернулся твой Go- контент)
P.S. Смотрю, с Goland в VSС перекатился?)
Чел рассказывает про чистую архитектуру, не понимая ее смысл и все подряд за интерфейсы прячет. Смысл чистой архитектуры в том что бизнес-логика инкапсулирована и не зависит ни от чего и мы спокойно можем перекинуть любой домен с бизнес логикой на другой сервис и все взлетит. У тебя же бизнес логика зависит от того какой контракт использует транспортер, должно быть наоборот транспортер должен зависеть от того какие методы есть в классах с бизнес логикой
Что думаешь об использовании HealthChecks для Докер Контейнеров? И да, вы планируете заворачивать ваше приложение в Kubernetes?
Спасибо, хорошо подал матерьял!
Но есть предложение, раздели файл с миграциями, разложи сущности по отдельным файлам, пакет migration это позволяет делать)
если один и тот же фейс используется в нескольких местах, то его надо хранить где-то в третьем месте
ета Okey )
Дублирование описания интерфейсов, это конечно лютая жесть. А советовать такое, жесть вдвойне. Сразу видно что у авторов кода нет опыта работы с плюсами, джавой и и.п. Действительно интерфейс описывается по месту использования, т.к. там мы не должны зависеть от реализации. Но что мешает вынести описание интерфейса в отдельный файл?!
То чувство, когда строил clean arch, а построил hexagonal )))
Расскажи про gRPC, было бы интересно посмотреть как пишется CRUD server
уже записал видео, скоро будет на канале
Отличное объяснение. Почему не вынести дублируемые интерфейсы в транспортах в отдельный файл в каталог transport?
Please, make video about hexagonal architecture or build a simple backend project using it?
Максим, добрый день)
Спасибо за видео)
Подскажи пожалуйста, а как бизнес логика реализует интерфейсы из транспортного уровня, на уровне языка?
Плюс в виде говорилось, что у уровней односторонняя связь, а объявление интерфейсов для уровня бизнес логики в транспортном уровне приводит к двусторонней зависимости уровней?
Странно, бизнес-логику мы хотим выделить в сервисный слой, чтобы разные транспорты не дублировали код, а валидацию предлагается все еще в транспорте делать
Максим, спасибо за труды!!! Последние месяцы пытаюсь понять реализацию чистой архитектуры и уже встречал такое же мнение насчёт описания и реализации интерфейсов, в частности я говорю об отрывке с 17:35 . Но мне как человеку, у которого нет реальных проектов за плечами (только учебные) не совсем понятна терминология. Я прям сейчас сижу и пишу в тетрадку: "интерфейсы описываются не на том уровне, где реализуются, а на том уровне, где используются". Для такого обывателя как я, "реализуются" и "используются" звучат как синонимы (и я раньше это тоже слышал, но не понял до сих пор что это значит системно). Я вижу на экране у вас разницу в компоновке по пакетам, однако, может у вас получиться дать четкие определения "реализации" и "использования" интерфейсов? На видео вы подбирали слова, когда объясняли, возможно и вам будет легче объяснить разницу в подходах, после углубления в тему.
Есть два понятия: декларация(объявление) и реализация
Декларация - это описание интерфейса, т.е. есть такая функция с такой сигнатурой
Реализация - это сам код функции, которая соответствует объявленной сигнатуре.
type Example interface {
Do(value uint) int
}
type ExampleStruct struct {}
func (es ExampleStruct) Do(value int) int {
return value
}
В плане концепции, это смена "я тебе передам такой тип" на "я ожидаю такой тип"
странно пишет транспортный а по картинке, транспортный не может соединяться с бд ....
Так а почему бы контракты сервисов не описывать на уровне самой бизнес-сущности?
Привет, у тебя интересный контент, убедительная просьба, поработай со своей речью. Читай художественную литературу вслух, работай у зеркала и тд. Спасибо за твой труд!
«В идеале описывать Интерфейс там, где Вы его используете..» таким же образом нарушим принцип DRY. В реальной разработке следует преследовать его?
у меня тоже возник такой вопрос, ведь если у сервиса будет зависимость другого сервиса, то описывать интерфейс придется и в сервис слое.
Я тоже над этим призадумался. Ведь, если абстрагироваться от Go, а взять язык, где необходимо конкретно указывать, какой интерфейс реализует структура. Получится, что некий репозиторий, полезет за интерфейсом на более высокий архитектурный слой, что быть получается не должно. А вот сервису, за интерфейсом репозитория, вниз спросить можно. Конкретно в Go, интерфейсы конечно реализуются не явно, но в душе все равно какое-то противоречие появляется.
Плюсую под комментарием, тоже хочу увидеть ответ Максима
Тоже плюсую
Короче разобрался. Вопрос спорный, однако если у нас множество раз используется какой-либо контракт (интерфейс) в различных сервисах, то имеет смысл выносить их в отдельную папку(пакет) и уже использовать их оттуда
С паттерном «команда», видимо, автор не знаком?
А почему ты в этом проекте выбрал Postgres вместо Mongo?
Максим,этот код есть на твоём GitHub?Не смог найти
нет
Разве можно путать слова структура проекта и архитектура?
3 недоступных видео скрыто. Это становится доступно для тех у кого куплен курс?
это видео, которые стоят на очереди публикации
Давно за тобой слежу, подскажи пожалуйста: Возможно ли начать учиться по твоим курсам с полного нуля или же лучше начать с другого популярного языка (с какого?) и потом переключиться на Go?)
С чего начал?
Что с твоим сайтом zaskevich?
Есть ли инфа по этому поводу?
Не продлил тариф на Tilda
медленно вещаешь очевидные вещи. ставим скорость 1.5х и слушаем...
Невозможно слушать этот говор, лучше бы уже на нэзалэжной вещал
@backendninja6737 чому перейшов на іншу IDE?