Почему интерфейсы лучше размещать в месте использования - GoLang best practices

  Рет қаралды 24,504

Николай Тузов — Golang

Николай Тузов — Golang

Күн бұрын

Почему важно описывать интерфейсы не рядом с реализацией, а в месте использования.
----
❤️ Если у вас есть желание поддержать развитие канала:
Секретный телеграм-канал:
- В рублях: t.me/+1UPXV_DGnG1mODJi
- В евро: t.me/+hedI8LevYTc5MDM6
boosty.to/nikolay.tuzov
/ tuzov
Другие проекты:
- 👾 Мой канал в Telegram: t.me/ntuzov
- 🗣 Чат в Telegram: t.me/+zsSZ63wEJDs3NGVi
- 👀 GoLang Digest: t.me/golang_digest - мои регулярные подборки интересных материалов по Go.
----
Тайм-коды
00:00 Вступление
00:32 Минималистичность интерфейсов
00:43 Независимость от реализации
00:57 Пример веб-сервиса
01:30 Чем этот сервис плох?
02:42 Как исправить? Интерфейсы по месту использования!
04:52 Уменьшилась связность системы
05:39 Улучшили понятность кода
07:02 Увеличили гибкость системы
08:03 Тестирование и моки
09:06 Минусы подхода
11:58 Утинная типизация - что это?
13:52 Заключение
#golang #ntuzov

Пікірлер: 103
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
👾Подписывайтесь на мой канал в Telegram: t.me/ntuzov ❤ Если у вас есть желание поддержать развитие канала: Секретный телеграм-канал: - В рублях: t.me/+1UPXV_DGnG1mODJi - В евро: t.me/+hedI8LevYTc5MDM6 boosty.to/nikolay.tuzov www.patreon.com/tuzov
@abylkhairnurgozhayev6089
@abylkhairnurgozhayev6089 Жыл бұрын
Николай можно пожалуйста с кафкой очень мало на инете таких видео
@BabyTigerOnTheSunflower
@BabyTigerOnTheSunflower Жыл бұрын
очень хотелось бы видео по мокам, да. Спасибо за огромную работу, которую Вы делаете!
@user-qi6vq3gb9s
@user-qi6vq3gb9s Жыл бұрын
Спасибо, ты лучший из ютуберов по го) по поводу mockery, использую эту библиотеку для юнит тестирования, но к сожалению опыта в тестах пока имею мало. Так что жду более широкого раскрытия данной темы)
@nikolaysheregeda7856
@nikolaysheregeda7856 Жыл бұрын
Любопытно сравнение с gomock, почему не эта либа выбрана для генерации моков?
@defanji8484
@defanji8484 Жыл бұрын
Как всегда отличное видео!) Спасибо за труд!
@user-zg8ij3kt1h
@user-zg8ij3kt1h 9 ай бұрын
Про моки очень интересно) И вообще, хотелось бы плейлист про тестирование целый. Успехов автору и развития каналу. Всем Go!
@dmitriysuhinin
@dmitriysuhinin Жыл бұрын
если мы будем рассматривать handler из реальной жизни, который оркестрирует например базой данный, кешем, дергает какие-то third party библиотеки ну и еще много чего он может делать у себя под капотом. обычно таких вот handler-ов может бы очень много если мы говорим о реальном приложении. так вот в таком случае получается будет очень много вот таких вот мелких интерфейсов, плюс многие из них будут/могут пересекаться своими методами. так же будет большая пачка моков делающих практически одно и тоже(их можно не хранить в самом проекте а генерировать только по надобности до запуска тестов). в общем в реальном приложении получается слишком большой оверхед по тому, сколько надо писать и поддерживать. к этому всему мы подключаем упомянутый факт, что иногда нам надо что-то поменять и тут начнется самое интересно даже при условии что IDE будет в этом помогать. в общем достаточно неоднозначный подход с большим количеством минусов на самом деле.
@maratfatkulov4993
@maratfatkulov4993 10 ай бұрын
Вы своим сообщением описали минус подхода из других яп с наследованием одного интерфейса как будто, а в конце сказали, что много минусов у гошного подхода. Можете, пожалуйста, дать пояснение?
@alexandrdeveloper1242
@alexandrdeveloper1242 9 ай бұрын
​@@maratfatkulov4993всë верно он описал. Это полное непонимание как работают интерфейсы. Начну по порядку: 1. То что интерфейс разбивается на методы может быть не плохо и соответствует single responsibility. Но это зависит от задачи. Если задача не требует, нет необходимости усложнять. В приведённом примере правильно оставить все методы хранилища в одном интерфейсе, т к они выполняют одну задачу - сохранение объекта для последующего получения. Есть также вариант архитектуры когда сохранение отделено от получения, но опять же что бы это было оправдано, вся архитектура приложения должна это использовать 2. Дак-тайпинг тут вообще не причём. Тем более его и нет в примере - все интерфейсы явно передаются и явно реализуются. 3. Где размещать интерфейсы? Точно не в месте использования, т к таких мест много! В этом и смысл интерфейса, что он формализует контракт, который применяется во многих местах. Подход из видео приведёт к дублированию кода, а в конечном счёте к тому что код перестанет быть унифицированным и станет не читаемым. Интерфейсы надо размещать в отдельном пакете с интерфейсами. Тем более если это граница слоёв приложения. 4. Кэш вместо хранилища... Или по другому, кэш делается декоратором (гуглить паттерн декоратор) На мой взгляд не удачное решение. Лучше делать его паттерном "стратегия". Т е передать внутрь реализации хранилища как зависимость и дать хранилищу им оперировать.
@invisibleinvisible83
@invisibleinvisible83 Жыл бұрын
Спасибо самые лучшие видео по golang ❤❤❤🙏🏻 А будут ли видео про многопоточность в golang, ещё бы очень интересно было послушать про профилирование. Спасибо за видео. Процветания каналу
@OdejmosO
@OdejmosO Жыл бұрын
Спасибо огромное за ваш контент!
@user-vz2gg1pf2m
@user-vz2gg1pf2m Жыл бұрын
Перемещение интерфейса к месту использования - это инверсия зависимости (soliD). Утиная типизация не убирает эту зависимость, и код репозитория должен соответствовать интерфейсу объявленному в пакете хэндлеров. Количество зависимостей (зацепление, а не связность) не уменьшилось, изменилось только направление зависимости. Инверсия зависимсоти обычно нужна для создания независимого слоя бизнес-логики. Бизнес-логика задаёт интерфейс взаимодействия с хранилищем, а не наоборот. Это кажется довольно очевидным, но я встречал код, в котором метод репозитория требует передачи коннекта к бд :-) Такое неправильное направление зависимости не позволяет заменить постгрес на мемкэш. Таким образом, интерфейс надо размещать не просто в месте использования, а там где он позволит задать правильное направление зависимости. Если бы на видео была бы какая-то бизнес-логика (например, ограничение количества созданных пользователей в день), и в доменном слое возник какой-то интерфейс, то переносить этот интерфейс в слой хэндлеров было бы непрактично.
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Звучит убедительно) А приходи в наш чатик, вдруг кто-то захочет подискутировать об этом: t.me/+WyjmnP6la_QyYjAy
@JanePilotessa
@JanePilotessa Жыл бұрын
А часто приходится менять БД на мем кеш?) Вопрос проброса коннекта (для транзакций) очень интересный, я видел 3 реализации: - проброс коннекта напрямую (очевидная и прозрачная работа, недостаток вы описали) - проброс внутри контекста (неочевидно и непрозрачно) - при каждом запросе создаётся экземпляр менеджера репозиториев с одним коннектом Поделитесь, как вы это делаете?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
​@@JanePilotessa 2-й вариант я бы сразу отбросил, слишком уж неочевидный Обычно в рабочих проектах коннект передаётся в конструктор, т.е. при создании экземпляра репозитория. Но в некоторых случаях бывает удобней передавать коннект в виде аргумента метода - например, когда мы хотим объединять в транзакцию несколько вызовов методов репозитория. Такие решения тоже встречаются.
@h3ckphy246
@h3ckphy246 5 ай бұрын
я что-то не могу понять последний абзац. Может кто-нибудь прояснить? В видео доменный слой он где? И зачем интерфейс доменного слоя переносить в слой хэндлеров? И как тут нарушается направление зависимости?
@user-vz2gg1pf2m
@user-vz2gg1pf2m 5 ай бұрын
@@h3ckphy246 в видео нет отдельного слоя бизнес-логики, так как пример очень простой. Я как раз отмечаю, что интерфейс доменного слоя не надо переносить куда бы то ни было. Переносить интерфейс надо не просто так, а с целью создать независимый слой приложения. Независимость упростит изменения кода в этом слое. А поскольку чаще всего меняется слой бизнес-логики, то обычно стараются сделать независимым именно его. Более подробно об этом можно почитать в очень интересной книжке Чистая архитектура Роберта Мартина.
@user-xh5mp4rc6g
@user-xh5mp4rc6g 4 ай бұрын
Спасибо за видео! Очень доступно и понятно объснил.
@dmitryibaranov6763
@dmitryibaranov6763 Жыл бұрын
Что выходит. Если в 2 разных местах надо получать пользователя, то будут описаны 2 интерфейса, которые полностью совпадают, но описаны в разных местах ? Таким образом получается некое нарушение dry ?
@parvizyuldashev4668
@parvizyuldashev4668 Жыл бұрын
Классное объяснение. Пошел внедрять в проекты! Ждем ролик по мокам)
@user-fv3ix6mt9x
@user-fv3ix6mt9x Жыл бұрын
Спасибо за развёрнутый ответ!
@user-zg8ij3kt1h
@user-zg8ij3kt1h 9 ай бұрын
Николай, благодарю за науку. Этой информации о том, как использовать "кубики" очень не хватает в курсах. В книгах это может быть, но часто это ещё и в голове нужно уложить. А тут инфа от практикующего кодера из первых уст т.с.
@user-zp5rt6qb4k
@user-zp5rt6qb4k Жыл бұрын
Отличный ролик! Жду с нетерпением ролик про моки
@eleimt
@eleimt Жыл бұрын
Будет видео о gRPC? Не соображу как в проекте добавить клиент для gRPC. Спасибо за труд и стримы.
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Будет =)
@johnb7657
@johnb7657 Жыл бұрын
@@nikolay_tuzov Благодарю, можно потом еще по мокам пройтись?
@eleimt
@eleimt Жыл бұрын
​@@nikolay_tuzov Клиент добавил. Теперь вопрос организации кода и в принципе как это поддерживать если выходит новая версия API.
@user-ps6bb1fm9u
@user-ps6bb1fm9u Жыл бұрын
Свичнулся в Go с другого языка в котором стандартная номинативная типизация и такой подход конечно кажется конечно не говнокодом, но болью. Тут следует смотреть, что мы чаще делаем с кодом. Есть такая аксиома в программировании - "код чаще читается, чем пишется". С этой позиции конечно с кодом становится работать куда менее удобно, придется 100500 файлов облазить, о чем сказано в видео. Этот недостаток лично для меня нивелирует преимущества от разделения интерфейсов.
@UAStriker
@UAStriker Жыл бұрын
Спасибо за ваш труд. Жду ролик про моки
@goroutine
@goroutine Жыл бұрын
Спасибо за видео. Хочется гайд по Mockery.
@SergiusBfg
@SergiusBfg 3 ай бұрын
Лучшее объяснение. Подпись
@MarkAnto7
@MarkAnto7 Жыл бұрын
Спасибо за видео. По мокам было бы интересно отдельное видео
@user-iy7rm7dt8x
@user-iy7rm7dt8x Жыл бұрын
Круто, жду ещё контент
@dazzle529
@dazzle529 Жыл бұрын
Спасибо автору за проделанную работу. Хотелось бы узнать такой же материал, касательно моделей и структур. Где лучше их размещать? Обычно в моих проектах они лежат в pkg/models, но видел как некоторые размещают их в месте реализации
@vladimireliseev7602
@vladimireliseev7602 Жыл бұрын
Благодарю за видео! А у Вас нет ссылки на какие-то официальные заявления авторитетных людей, чтобы можно было не только дать ссылку на Ваше видео, но и дать ссылку на сообщение в доке, где черным по белому написано - интерфейс должен быть размещен в месте использования.
@dimmodddimmodd7199
@dimmodddimmodd7199 Жыл бұрын
Perfect !
@normalnoenazvaniedlyaslaba4566
@normalnoenazvaniedlyaslaba4566 Ай бұрын
Очень круто, спасибо! Только не совсем понятно, как это делать, когда я, например пишу grpc сервис, ведь там сигнатуры функции уже фиксированы
@prayer4675
@prayer4675 11 ай бұрын
Николай, а что будет, если сигнатура метода Use() в исходном интерфейсе взяла и поменялась? Мало того, что в хендлерах это сразу не узнают, так ещё и исправлять придётся массу вот таких вот дополнительных интерфейсов с тем же методом.
@user-ej9wr7sw7r
@user-ej9wr7sw7r Жыл бұрын
спасибо. Видео про моки было бы полезно.
@user-ge2bv2jt7c
@user-ge2bv2jt7c Жыл бұрын
Добрый день, спасибо за видео. На практике столкнулись с тем, что такой подход не удобен в случае, если необходимо вернуть интерфейс. Например, есть некое хранилище балансов. Баланс реализован сложно на основе event sourcing. Хранилище дальше инъецируется в другие структуры. В этом случае, если использовать такой подход, то это значительно усложняет тестирование, потому что возвращается именно баланс с конкретной реализацией, который совсем не просто привести в нужное состояние. Если же сделать хранилище с возвращаемым интерфейсом, то утиная типизация перестаёт работать. Go не может понять, что передаваемый извне интерфейс, пусть и совпадающий по сигнатуре, соответствует локальному интерфейсу баланса. В итоге, для таких случаев приходится делать один внешний общий интерфейс балансов, который уже используется везде.
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Спасибо за такой развёрнутый комментарий. У меня есть подозрение, что описанный тобой подход не очень правильный. Но это хорошая тема для обсуждения - приходи в наш чатик Gopher Club, обсудим (см. ссылку в описании).
@JanePilotessa
@JanePilotessa Жыл бұрын
Вполне нормальное решение хранить интерфейс в отдельном пакете, если это требуется. Например мы делаем инверсию зависимости логера, там 5 методов. Не плодить же нам миллион однотипных интерфейсов:)
@micbalmicbalov9955
@micbalmicbalov9955 Жыл бұрын
Большое спасибо! Очень интересно и полезно. Если есть возможность, покажите два минимальных проекта отличающихся наличием и отсутствием интерфейса. И какие плюсы у того у которого интерфейс есть?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Ух.. Больно будет писать целый проект без интерфейсов, даже минимальный(
@user-tv5pd2pv9q
@user-tv5pd2pv9q 5 ай бұрын
Можно уточнить по поводу интерфейса логера? Для него допустимо описать интерфейс не по месту использования?
@fprotimaru1944
@fprotimaru1944 Жыл бұрын
Как насчет DTO между интерфейсами?
@user-name-2598
@user-name-2598 2 ай бұрын
Да, о МОК очень хотелось бы узнать! Запиши видео, пожалуйста)
@nikolay_tuzov
@nikolay_tuzov 2 ай бұрын
Уже давно записал, ищи на канале)
@user-name-2598
@user-name-2598 2 ай бұрын
@@nikolay_tuzov Внимание автора к аудитории очень приятно) Спасибо, что ответил! Даже спустя год от публикации видео. Хочу сказать, что у тебя очень понятные, классные видео, огромное спасибо за твой труд! Ты очень помогаешь новичкам, твои "ультимативные" видео пересылаем друг другу, как золотой стандарт исчерпывающей информации)) Большое спасибо!
@mromrrom
@mromrrom Жыл бұрын
да, хотелось бы поподробнее про generate, плиз
@user-gr4ru1zs5d
@user-gr4ru1zs5d Жыл бұрын
видео по мокам ! Було б куруто . Дякую за Вашу роботу
@user-jd3sj6fl9q
@user-jd3sj6fl9q Жыл бұрын
Николай, спасибо за видео. Вопрос: я немного не понял, вы сказали, что этот подход уменьшает связность, но в хендлере у вас все равно осталась зависимость от импорта структуры User, или подразумевается, что структуры лежат в независимом пакете, где лежат модели условные?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Да, именно так - в отдельном пакете
@user-jd3sj6fl9q
@user-jd3sj6fl9q Жыл бұрын
@@nikolay_tuzov а это go way? Я уже реально запутался, одну статью читаешь, там говорят, что храните модели прямо в сервисе с бизнес логикой и что package models это плохо, в другой говорят, что храните модели в отдельном пакете от сервиса. А где истина то?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
@@user-jd3sj6fl9q истина, как обычно, где-то рядом =) Не пытайся найти какое-то "абсолютное мнение". Выслушивай аргументы всех сторон, взвешивай, сравнивай, делай выводы сам.
@r_888_88
@r_888_88 Жыл бұрын
Про моки интересно было бы послушать
@richtermnd6163
@richtermnd6163 6 ай бұрын
А если описывать эти мини интерфейсы как раз в storage, а общий крупный интерфейс создавать путем их композиции?
@eleimt
@eleimt Жыл бұрын
Пишу комментарий про строчку go:generate :)
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Копать сюда: eli.thegreenplace.net/2021/a-comprehensive-guide-to-go-generate/ Как доберутся руки, сделаю об этом отдельный видос
@Igor-yh4gl
@Igor-yh4gl Жыл бұрын
Привет, на 5:09 повторяется фраза и где-то дальше по видео тоже. Видимо была перезапись и чет недомонтировалось.
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Ага, недомонтировалось, проглядел ( Но, вроде, не сильно мешает просмотру
@Dantesik1
@Dantesik1 Жыл бұрын
От данного автора узнаю больше чем от родителей за всю свою жизнь
@londerru
@londerru Жыл бұрын
Не знаю, мож короткий видос сделаешь как делаются(пишутся) разные движки для игр, чтобы вот объединялись в итоге анимация модели движения, ну в чём некая суть пояснить
@hurricane-rus
@hurricane-rus 5 ай бұрын
Вопрос про файлы, где у нас интерфейс с одним методом и сразу же его реализация. А в этом случае зачем нам вообще интерфейс? Т.е. почему его не выкинуть (как лишнюю обертку) и не написать сразу обычную функцию под наш конкретный объект? Ведь плюс интерфейсов прежде всего в том, что мы можем использовать один интерфейс в нескольких местах - это и есть полиморфизм. А полиморфизм из одной реализации вроде как не совсем полиморфизм, нет)?
@unlite2896
@unlite2896 9 ай бұрын
Классный подход, правда при нем получается, что вместо одной структуры Handler с условными методами CreateUser, GetUser, DeleteUser, UpdateUser, которая принимает один интерфейс Storage со всеми методами, нам придется иметь много структур-хендлеров под каждый метод, то есть CreateUserHandler, GetUserHandler, итд. И соответственно весь этот огромный список инициализировать в main. А когда таких хендлеров десятки или сотни, не начинает ли это выглядеть слишком монструзным, или даже в таком случае продолжают использовать такой подход?
@nikolay_tuzov
@nikolay_tuzov 9 ай бұрын
В main ты инициализируешь лишь одну структуру - Storage, и он один реализует все частные интерфейсы всех хендлеров. Дублируется лишь описание интерфейса.
@prayer4675
@prayer4675 11 ай бұрын
Почему-то изображение и звук немного не совпадают по времени.
@JoeFantor
@JoeFantor Жыл бұрын
Мы все равно не отвязались от пакета, т.к. ещё ссылаемся на модель из этого пакета. Как с этим быть?
@aidarark5558
@aidarark5558 Жыл бұрын
Наверно dto создавать, хотя мне такая практика не особо нравится
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
С моделями мы в любом случае будем связаны, и тут уже ничего не поделаешь. Как вариант, можно создать отдельный пакет models, или что-то подобное, чтобы не зависеть конкретно от Storage. Но тут уже нужно исходить из контекста самого проекта.
@user-om1pz6un8z
@user-om1pz6un8z Жыл бұрын
​@@nikolay_tuzov Не мог бы ты привести кейсы когда модели нужно оставлять рядом со стораджем и оставлять зависимость хэндлера от стораджа?
@rogozhka-racing
@rogozhka-racing Жыл бұрын
Не очень понятно, почему интерфейсы в месте использования сделаны экспортируемыми (публичными)? Полагаю приватный вариант был бы более корректен. Вообще экспортируемый интерфейс - это что-то глобальное, скорее прерогатива sdk, определять экспортируемые интерфейсы для повсеместного использования. Сложно что-то придумать, что будет гарантированно использоваться всеми частями проекта. Даже логгер, по той же логике может быть приватным, и часть объектов использует часть возможностей логирования, которую и описывает в месте использования.
@Michel_de_Montaigne
@Michel_de_Montaigne 6 ай бұрын
Кто читал совершенный код, заметит ещё одно преимущество в таком подходе.
@brosit-kurit
@brosit-kurit 5 ай бұрын
А уже вышло видео про mock
@maxdzh212
@maxdzh212 Жыл бұрын
Интерфейс который объявлен рядом с использованием нужно объявлять приватным, так как нет нужды ему быть публичным. И пример с использованием storage в слое транспорта выглядит не очень, так как это означает что бизнес логика находится либо в слое транспорта, либо в слое базы данных. Бизнес логика в транспорте это плохо, так как при смене транспорта придется логику переносить и в целом это нарушает high cohesion. Бизнес логика в слое базы данных даже хуже, потому что есть риск реализовать логику на языке sql, а при смене базы данных переписывать ее заново
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Хорошие замечания. На счет приватности интерфейса точно согласен. Остальное дискутивно, но звучит тоже справедливо.
@user-ju7xj3qu6k
@user-ju7xj3qu6k 5 ай бұрын
Я предпочитаю выносить интерфейсы в отдельный модуль и проектировать из так, чтобы они опирались только на интерфейсы и стандартные типы. Это позволяет модулям реализации и использования вообще не знать друг о друге.
@dmitriyobidin6049
@dmitriyobidin6049 9 ай бұрын
Конечно в месте использования. Описывать интерфейсы в месте реализации - это где? Если структуры их реализуют неявно - то как понять где у нас место реализации? Сама задача невыполнима, не говоря уже о ее нелогичности.
@dimitrobest5293
@dimitrobest5293 Жыл бұрын
камера закривает код, можно слева внизу разместить
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Учту, спасибо
@fprotimaru1944
@fprotimaru1944 Жыл бұрын
Бро, попробуй New UI от Jetbrains
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Я пока морально не готов к этому))
@ViktorPolyakov15
@ViktorPolyakov15 8 ай бұрын
А насколько бесплатны интерфейсы в гошке?
@nikolay_tuzov
@nikolay_tuzov 8 ай бұрын
Не бесплатны - как в плане памяти, так и в плане быстродействия. А насколько, тут уже нужно разбирать конкретные случаи. Можете глянуть этот мой ролик, например: kzbin.info/www/bejne/Y5S7YXanfJulnaM Он шуточный, конечно! Но замеры в части про интерфейсы вполне честные. Шуточные там только выводы, которые я из этого делаю.
@ViktorPolyakov15
@ViktorPolyakov15 8 ай бұрын
@@nikolay_tuzov Ага, спасибо за пример. А насчет видео по ссылке... Вот вы там шутили, а я сейчас работаю с людьми, которые именно так и думают на полном серьезе и переубедить их невозможно. Хорошо только одно - они работают в соседней команде.
@ViktorPolyakov15
@ViktorPolyakov15 8 ай бұрын
@@nikolay_tuzov Спасибо за тест, только вот ссылки на его код я под видео не нашел. А насчет самого ролика... вы вот там шутите, а я работаю с людьми которые именно так и пишут код. Хорошо только одно, что они работают в соседней команде.
@nikolay_tuzov
@nikolay_tuzov 8 ай бұрын
@@ViktorPolyakov15 бывает, я тоже с такими сталкивался =)
@batpyiiikob7245
@batpyiiikob7245 6 ай бұрын
Спасибо!
@andreipopov2700
@andreipopov2700 Жыл бұрын
Видео по мокам +1
@iqMoreThatZero
@iqMoreThatZero 8 ай бұрын
Мы становимся не зависимым от storage.user? Ага. А то что мы отдаём storage.users.User ниче?
@somebodycrazy
@somebodycrazy 4 ай бұрын
Это конечно сильно... закрывать часть кода своим лицом. Спрашивается, для чего? Можно было бы окно с лицом сделать в два три раза меньше и этого было бы достаточно, или допустим включать иногда, в важных моментах. Некоторые вообще не выводят лица, что увеличивает объем рабочей области, за что благодарности авторам. Самое лучшее, это показать вначале, и в конце видео, вполне достаточно.
@user-qx3km6wp1p
@user-qx3km6wp1p Жыл бұрын
Размещение интерфейсов в месте использования является правильным подходом и в c++ и в других подобных языках. Никакой специфики go в этом нет. Если для кого-то это кажется странным, возникает большой вопрос к его профессионализму
@ThePirateHistory
@ThePirateHistory 6 ай бұрын
Видос досмотрел, так как видел анотацию в видео про url-shortnere, а в чём проблема чтобы создать не целый объект Users, а тот же ЮзерКреайте, и не нужно будет создавать все методы, хотя странно раз ты меняешь хранилище, то по идеи нужно переписывать всё, а если лишь просто часть заменить, не большие куски, то можно их ведь вынести
@georgiy_kulagin
@georgiy_kulagin Жыл бұрын
Пишу комментарий про строчку go:generate :)
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Предыдущему товарищу ответил, продублирую)) Копать сюда: eli.thegreenplace.net/2021/a-comprehensive-guide-to-go-generate/ Как доберутся руки, сделаю об этом отдельный видос
@georgiy_kulagin
@georgiy_kulagin Жыл бұрын
@@nikolay_tuzov спасибо
Генерация и использование моков в Go / Mockery
23:35
Николай Тузов — Golang
Рет қаралды 16 М.
Как на самом деле устроен тип Map в Golang? | Golang под капотом
34:33
Шокирующая Речь Выпускника 😳📽️@CarrolltonTexas
00:43
Глеб Рандалайнен
Рет қаралды 12 МЛН
Кәріс өшін алды...| Synyptas 3 | 10 серия
24:51
kak budto
Рет қаралды 1,3 МЛН
WHO DO I LOVE MOST?
00:22
dednahype
Рет қаралды 27 МЛН
Which one of them is cooler?😎 @potapova_blog
00:45
Filaretiki
Рет қаралды 3,6 МЛН
Как на самом деле устроены каналы в Golang? | Golang channels internals
41:31
C++ собеседование в 2024 году
1:00:33
Владимир в IT
Рет қаралды 4,4 М.
Архитектура Go проекта на практике
30:09
Evrone Development
Рет қаралды 12 М.
Всё про конкурентность в Go
23:36
defer panic
Рет қаралды 13 М.
Redis за 20 минут
23:22
suchkov tech
Рет қаралды 99 М.
Шокирующая Речь Выпускника 😳📽️@CarrolltonTexas
00:43
Глеб Рандалайнен
Рет қаралды 12 МЛН