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

Sdílet
Vložit
  • čas přidán 7. 06. 2024
  • Почему важно описывать интерфейсы не рядом с реализацией, а в месте использования.
    ----
    ❤️ Если у вас есть желание поддержать развитие канала:
    Секретный телеграм-канал:
    - В рублях: 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

Komentáře • 103

  • @nikolay_tuzov
    @nikolay_tuzov  Před rokem +5

    👾Подписывайтесь на мой канал в Telegram: t.me/ntuzov
    ❤ Если у вас есть желание поддержать развитие канала:
    Секретный телеграм-канал:
    - В рублях: t.me/+1UPXV_DGnG1mODJi
    - В евро: t.me/+hedI8LevYTc5MDM6
    boosty.to/nikolay.tuzov
    www.patreon.com/tuzov

    • @abylkhairnurgozhayev6089
      @abylkhairnurgozhayev6089 Před rokem

      Николай можно пожалуйста с кафкой очень мало на инете таких видео

  • @BabyTigerOnTheSunflower
    @BabyTigerOnTheSunflower Před rokem +12

    очень хотелось бы видео по мокам, да. Спасибо за огромную работу, которую Вы делаете!

  • @defanji8484
    @defanji8484 Před rokem +4

    Как всегда отличное видео!) Спасибо за труд!

  • @user-qi6vq3gb9s
    @user-qi6vq3gb9s Před rokem +24

    Спасибо, ты лучший из ютуберов по го) по поводу mockery, использую эту библиотеку для юнит тестирования, но к сожалению опыта в тестах пока имею мало. Так что жду более широкого раскрытия данной темы)

    • @nikolaysheregeda7856
      @nikolaysheregeda7856 Před rokem

      Любопытно сравнение с gomock, почему не эта либа выбрана для генерации моков?

  • @user-zg8ij3kt1h
    @user-zg8ij3kt1h Před 8 měsíci +1

    Про моки очень интересно) И вообще, хотелось бы плейлист про тестирование целый. Успехов автору и развития каналу. Всем Go!

  • @invisibleinvisible83
    @invisibleinvisible83 Před rokem +1

    Спасибо самые лучшие видео по golang ❤❤❤🙏🏻 А будут ли видео про многопоточность в golang, ещё бы очень интересно было послушать про профилирование. Спасибо за видео. Процветания каналу

  • @parvizyuldashev4668
    @parvizyuldashev4668 Před rokem

    Классное объяснение. Пошел внедрять в проекты! Ждем ролик по мокам)

  • @OdejmosO
    @OdejmosO Před rokem +1

    Спасибо огромное за ваш контент!

  • @eleimt
    @eleimt Před rokem +15

    Будет видео о gRPC? Не соображу как в проекте добавить клиент для gRPC. Спасибо за труд и стримы.

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +3

      Будет =)

    • @johnb7657
      @johnb7657 Před rokem

      @@nikolay_tuzov Благодарю, можно потом еще по мокам пройтись?

    • @eleimt
      @eleimt Před rokem

      ​@@nikolay_tuzov Клиент добавил. Теперь вопрос организации кода и в принципе как это поддерживать если выходит новая версия API.

  • @user-zp5rt6qb4k
    @user-zp5rt6qb4k Před rokem

    Отличный ролик! Жду с нетерпением ролик про моки

  • @user-xh5mp4rc6g
    @user-xh5mp4rc6g Před 3 měsíci

    Спасибо за видео!
    Очень доступно и понятно объснил.

  • @user-zg8ij3kt1h
    @user-zg8ij3kt1h Před 8 měsíci +1

    Николай, благодарю за науку. Этой информации о том, как использовать "кубики" очень не хватает в курсах. В книгах это может быть, но часто это ещё и в голове нужно уложить. А тут инфа от практикующего кодера из первых уст т.с.

  • @dmitriysuhinin
    @dmitriysuhinin Před rokem +14

    если мы будем рассматривать handler из реальной жизни, который оркестрирует например базой данный, кешем, дергает какие-то third party библиотеки ну и еще много чего он может делать у себя под капотом. обычно таких вот handler-ов может бы очень много если мы говорим о реальном приложении. так вот в таком случае получается будет очень много вот таких вот мелких интерфейсов, плюс многие из них будут/могут пересекаться своими методами. так же будет большая пачка моков делающих практически одно и тоже(их можно не хранить в самом проекте а генерировать только по надобности до запуска тестов). в общем в реальном приложении получается слишком большой оверхед по тому, сколько надо писать и поддерживать. к этому всему мы подключаем упомянутый факт, что иногда нам надо что-то поменять и тут начнется самое интересно даже при условии что IDE будет в этом помогать. в общем достаточно неоднозначный подход с большим количеством минусов на самом деле.

    • @maratfatkulov4993
      @maratfatkulov4993 Před 10 měsíci

      Вы своим сообщением описали минус подхода из других яп с наследованием одного интерфейса как будто, а в конце сказали, что много минусов у гошного подхода. Можете, пожалуйста, дать пояснение?

    • @alexandrdeveloper1242
      @alexandrdeveloper1242 Před 8 měsíci

      ​@@maratfatkulov4993всë верно он описал. Это полное непонимание как работают интерфейсы. Начну по порядку:
      1. То что интерфейс разбивается на методы может быть не плохо и соответствует single responsibility. Но это зависит от задачи. Если задача не требует, нет необходимости усложнять. В приведённом примере правильно оставить все методы хранилища в одном интерфейсе, т к они выполняют одну задачу - сохранение объекта для последующего получения. Есть также вариант архитектуры когда сохранение отделено от получения, но опять же что бы это было оправдано, вся архитектура приложения должна это использовать
      2. Дак-тайпинг тут вообще не причём. Тем более его и нет в примере - все интерфейсы явно передаются и явно реализуются.
      3. Где размещать интерфейсы? Точно не в месте использования, т к таких мест много! В этом и смысл интерфейса, что он формализует контракт, который применяется во многих местах. Подход из видео приведёт к дублированию кода, а в конечном счёте к тому что код перестанет быть унифицированным и станет не читаемым. Интерфейсы надо размещать в отдельном пакете с интерфейсами. Тем более если это граница слоёв приложения.
      4. Кэш вместо хранилища... Или по другому, кэш делается декоратором (гуглить паттерн декоратор) На мой взгляд не удачное решение. Лучше делать его паттерном "стратегия". Т е передать внутрь реализации хранилища как зависимость и дать хранилищу им оперировать.

  • @user-vz2gg1pf2m
    @user-vz2gg1pf2m Před rokem +21

    Перемещение интерфейса к месту использования - это инверсия зависимости (soliD). Утиная типизация не убирает эту зависимость, и код репозитория должен соответствовать интерфейсу объявленному в пакете хэндлеров. Количество зависимостей (зацепление, а не связность) не уменьшилось, изменилось только направление зависимости.
    Инверсия зависимсоти обычно нужна для создания независимого слоя бизнес-логики. Бизнес-логика задаёт интерфейс взаимодействия с хранилищем, а не наоборот. Это кажется довольно очевидным, но я встречал код, в котором метод репозитория требует передачи коннекта к бд :-) Такое неправильное направление зависимости не позволяет заменить постгрес на мемкэш.
    Таким образом, интерфейс надо размещать не просто в месте использования, а там где он позволит задать правильное направление зависимости. Если бы на видео была бы какая-то бизнес-логика (например, ограничение количества созданных пользователей в день), и в доменном слое возник какой-то интерфейс, то переносить этот интерфейс в слой хэндлеров было бы непрактично.

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +2

      Звучит убедительно)
      А приходи в наш чатик, вдруг кто-то захочет подискутировать об этом: t.me/+WyjmnP6la_QyYjAy

    • @JanePilotessa
      @JanePilotessa Před rokem

      А часто приходится менять БД на мем кеш?)
      Вопрос проброса коннекта (для транзакций) очень интересный, я видел 3 реализации:
      - проброс коннекта напрямую (очевидная и прозрачная работа, недостаток вы описали)
      - проброс внутри контекста (неочевидно и непрозрачно)
      - при каждом запросе создаётся экземпляр менеджера репозиториев с одним коннектом
      Поделитесь, как вы это делаете?

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +1

      ​@@JanePilotessa 2-й вариант я бы сразу отбросил, слишком уж неочевидный
      Обычно в рабочих проектах коннект передаётся в конструктор, т.е. при создании экземпляра репозитория.
      Но в некоторых случаях бывает удобней передавать коннект в виде аргумента метода - например, когда мы хотим объединять в транзакцию несколько вызовов методов репозитория. Такие решения тоже встречаются.

    • @h3ckphy246
      @h3ckphy246 Před 5 měsíci

      я что-то не могу понять последний абзац. Может кто-нибудь прояснить? В видео доменный слой он где? И зачем интерфейс доменного слоя переносить в слой хэндлеров? И как тут нарушается направление зависимости?

    • @user-vz2gg1pf2m
      @user-vz2gg1pf2m Před 5 měsíci +1

      @@h3ckphy246 в видео нет отдельного слоя бизнес-логики, так как пример очень простой. Я как раз отмечаю, что интерфейс доменного слоя не надо переносить куда бы то ни было.
      Переносить интерфейс надо не просто так, а с целью создать независимый слой приложения. Независимость упростит изменения кода в этом слое. А поскольку чаще всего меняется слой бизнес-логики, то обычно стараются сделать независимым именно его.
      Более подробно об этом можно почитать в очень интересной книжке Чистая архитектура Роберта Мартина.

  • @user-fv3ix6mt9x
    @user-fv3ix6mt9x Před rokem +1

    Спасибо за развёрнутый ответ!

  • @vladimireliseev7602
    @vladimireliseev7602 Před rokem

    Благодарю за видео!
    А у Вас нет ссылки на какие-то официальные заявления авторитетных людей, чтобы можно было не только дать ссылку на Ваше видео, но и дать ссылку на сообщение в доке, где черным по белому написано - интерфейс должен быть размещен в месте использования.

  • @dmitryibaranov6763
    @dmitryibaranov6763 Před rokem +5

    Что выходит. Если в 2 разных местах надо получать пользователя, то будут описаны 2 интерфейса, которые полностью совпадают, но описаны в разных местах ? Таким образом получается некое нарушение dry ?

  • @user-iy7rm7dt8x
    @user-iy7rm7dt8x Před rokem

    Круто, жду ещё контент

  • @UAStriker
    @UAStriker Před rokem

    Спасибо за ваш труд. Жду ролик про моки

  • @dazzle529
    @dazzle529 Před rokem

    Спасибо автору за проделанную работу. Хотелось бы узнать такой же материал, касательно моделей и структур. Где лучше их размещать? Обычно в моих проектах они лежат в pkg/models, но видел как некоторые размещают их в месте реализации

  • @SergiusBfg
    @SergiusBfg Před 3 měsíci

    Лучшее объяснение. Подпись

  • @goroutine
    @goroutine Před rokem

    Спасибо за видео. Хочется гайд по Mockery.

  • @prayer4675
    @prayer4675 Před 10 měsíci +1

    Николай, а что будет, если сигнатура метода Use() в исходном интерфейсе взяла и поменялась? Мало того, что в хендлерах это сразу не узнают, так ещё и исправлять придётся массу вот таких вот дополнительных интерфейсов с тем же методом.

  • @MarkAnto7
    @MarkAnto7 Před rokem

    Спасибо за видео. По мокам было бы интересно отдельное видео

  • @user-ps6bb1fm9u
    @user-ps6bb1fm9u Před rokem +4

    Свичнулся в Go с другого языка в котором стандартная номинативная типизация и такой подход конечно кажется конечно не говнокодом, но болью. Тут следует смотреть, что мы чаще делаем с кодом. Есть такая аксиома в программировании - "код чаще читается, чем пишется". С этой позиции конечно с кодом становится работать куда менее удобно, придется 100500 файлов облазить, о чем сказано в видео. Этот недостаток лично для меня нивелирует преимущества от разделения интерфейсов.

  • @dimmodddimmodd7199
    @dimmodddimmodd7199 Před rokem +1

    Perfect !

  • @micbalmicbalov9955
    @micbalmicbalov9955 Před rokem +4

    Большое спасибо! Очень интересно и полезно. Если есть возможность, покажите два минимальных проекта отличающихся наличием и отсутствием интерфейса. И какие плюсы у того у которого интерфейс есть?

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +1

      Ух.. Больно будет писать целый проект без интерфейсов, даже минимальный(

  • @user-tv5pd2pv9q
    @user-tv5pd2pv9q Před 5 měsíci

    Можно уточнить по поводу интерфейса логера? Для него допустимо описать интерфейс не по месту использования?

  • @normalnoenazvaniedlyaslaba4566

    Очень круто, спасибо! Только не совсем понятно, как это делать, когда я, например пишу grpc сервис, ведь там сигнатуры функции уже фиксированы

  • @fprotimaru1944
    @fprotimaru1944 Před rokem +1

    Как насчет DTO между интерфейсами?

  • @user-ge2bv2jt7c
    @user-ge2bv2jt7c Před rokem +3

    Добрый день, спасибо за видео. На практике столкнулись с тем, что такой подход не удобен в случае, если необходимо вернуть интерфейс.
    Например, есть некое хранилище балансов. Баланс реализован сложно на основе event sourcing. Хранилище дальше инъецируется в другие структуры.
    В этом случае, если использовать такой подход, то это значительно усложняет тестирование, потому что возвращается именно баланс с конкретной реализацией, который совсем не просто привести в нужное состояние.
    Если же сделать хранилище с возвращаемым интерфейсом, то утиная типизация перестаёт работать. Go не может понять, что передаваемый извне интерфейс, пусть и совпадающий по сигнатуре, соответствует локальному интерфейсу баланса.
    В итоге, для таких случаев приходится делать один внешний общий интерфейс балансов, который уже используется везде.

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem

      Спасибо за такой развёрнутый комментарий. У меня есть подозрение, что описанный тобой подход не очень правильный. Но это хорошая тема для обсуждения - приходи в наш чатик Gopher Club, обсудим (см. ссылку в описании).

    • @JanePilotessa
      @JanePilotessa Před rokem +3

      Вполне нормальное решение хранить интерфейс в отдельном пакете, если это требуется. Например мы делаем инверсию зависимости логера, там 5 методов. Не плодить же нам миллион однотипных интерфейсов:)

  • @user-jd3sj6fl9q
    @user-jd3sj6fl9q Před rokem +1

    Николай, спасибо за видео. Вопрос: я немного не понял, вы сказали, что этот подход уменьшает связность, но в хендлере у вас все равно осталась зависимость от импорта структуры User, или подразумевается, что структуры лежат в независимом пакете, где лежат модели условные?

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem

      Да, именно так - в отдельном пакете

    • @user-jd3sj6fl9q
      @user-jd3sj6fl9q Před rokem

      @@nikolay_tuzov а это go way? Я уже реально запутался, одну статью читаешь, там говорят, что храните модели прямо в сервисе с бизнес логикой и что package models это плохо, в другой говорят, что храните модели в отдельном пакете от сервиса. А где истина то?

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem

      @@user-jd3sj6fl9q истина, как обычно, где-то рядом =) Не пытайся найти какое-то "абсолютное мнение". Выслушивай аргументы всех сторон, взвешивай, сравнивай, делай выводы сам.

  • @user-ej9wr7sw7r
    @user-ej9wr7sw7r Před rokem +1

    спасибо. Видео про моки было бы полезно.

  • @user-gr4ru1zs5d
    @user-gr4ru1zs5d Před rokem

    видео по мокам ! Було б куруто . Дякую за Вашу роботу

  • @mromrrom
    @mromrrom Před rokem

    да, хотелось бы поподробнее про generate, плиз

  • @user-name-2598
    @user-name-2598 Před 2 měsíci

    Да, о МОК очень хотелось бы узнать! Запиши видео, пожалуйста)

    • @nikolay_tuzov
      @nikolay_tuzov  Před 2 měsíci +1

      Уже давно записал, ищи на канале)

    • @user-name-2598
      @user-name-2598 Před 2 měsíci

      @@nikolay_tuzov Внимание автора к аудитории очень приятно) Спасибо, что ответил! Даже спустя год от публикации видео.
      Хочу сказать, что у тебя очень понятные, классные видео, огромное спасибо за твой труд! Ты очень помогаешь новичкам, твои "ультимативные" видео пересылаем друг другу, как золотой стандарт исчерпывающей информации)) Большое спасибо!

  • @Igor-yh4gl
    @Igor-yh4gl Před rokem

    Привет, на 5:09 повторяется фраза и где-то дальше по видео тоже. Видимо была перезапись и чет недомонтировалось.

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +1

      Ага, недомонтировалось, проглядел (
      Но, вроде, не сильно мешает просмотру

  • @richtermnd6163
    @richtermnd6163 Před 6 měsíci

    А если описывать эти мини интерфейсы как раз в storage, а общий крупный интерфейс создавать путем их композиции?

  • @r_888_88
    @r_888_88 Před rokem

    Про моки интересно было бы послушать

  • @londerru
    @londerru Před rokem

    Не знаю, мож короткий видос сделаешь как делаются(пишутся) разные движки для игр, чтобы вот объединялись в итоге анимация модели движения, ну в чём некая суть пояснить

  • @hurricane-rus
    @hurricane-rus Před 5 měsíci

    Вопрос про файлы, где у нас интерфейс с одним методом и сразу же его реализация.
    А в этом случае зачем нам вообще интерфейс? Т.е. почему его не выкинуть (как лишнюю обертку) и не написать сразу обычную функцию под наш конкретный объект?
    Ведь плюс интерфейсов прежде всего в том, что мы можем использовать один интерфейс в нескольких местах - это и есть полиморфизм.
    А полиморфизм из одной реализации вроде как не совсем полиморфизм, нет)?

  • @unlite2896
    @unlite2896 Před 9 měsíci

    Классный подход, правда при нем получается, что вместо одной структуры Handler с условными методами CreateUser, GetUser, DeleteUser, UpdateUser, которая принимает один интерфейс Storage со всеми методами, нам придется иметь много структур-хендлеров под каждый метод, то есть CreateUserHandler, GetUserHandler, итд. И соответственно весь этот огромный список инициализировать в main. А когда таких хендлеров десятки или сотни, не начинает ли это выглядеть слишком монструзным, или даже в таком случае продолжают использовать такой подход?

    • @nikolay_tuzov
      @nikolay_tuzov  Před 9 měsíci

      В main ты инициализируешь лишь одну структуру - Storage, и он один реализует все частные интерфейсы всех хендлеров. Дублируется лишь описание интерфейса.

  • @Dantesik1
    @Dantesik1 Před rokem +2

    От данного автора узнаю больше чем от родителей за всю свою жизнь

  • @eleimt
    @eleimt Před rokem +5

    Пишу комментарий про строчку go:generate :)

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +2

      Копать сюда: eli.thegreenplace.net/2021/a-comprehensive-guide-to-go-generate/
      Как доберутся руки, сделаю об этом отдельный видос

  • @prayer4675
    @prayer4675 Před 10 měsíci

    Почему-то изображение и звук немного не совпадают по времени.

  • @brosit-kurit
    @brosit-kurit Před 5 měsíci

    А уже вышло видео про mock

  • @rogozhka-racing
    @rogozhka-racing Před rokem +1

    Не очень понятно, почему интерфейсы в месте использования сделаны экспортируемыми (публичными)? Полагаю приватный вариант был бы более корректен. Вообще экспортируемый интерфейс - это что-то глобальное, скорее прерогатива sdk, определять экспортируемые интерфейсы для повсеместного использования. Сложно что-то придумать, что будет гарантированно использоваться всеми частями проекта. Даже логгер, по той же логике может быть приватным, и часть объектов использует часть возможностей логирования, которую и описывает в месте использования.

  • @JoeFantor
    @JoeFantor Před rokem +1

    Мы все равно не отвязались от пакета, т.к. ещё ссылаемся на модель из этого пакета. Как с этим быть?

    • @aidarark5558
      @aidarark5558 Před rokem

      Наверно dto создавать, хотя мне такая практика не особо нравится

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +1

      С моделями мы в любом случае будем связаны, и тут уже ничего не поделаешь. Как вариант, можно создать отдельный пакет models, или что-то подобное, чтобы не зависеть конкретно от Storage. Но тут уже нужно исходить из контекста самого проекта.

    • @user-om1pz6un8z
      @user-om1pz6un8z Před rokem

      ​@@nikolay_tuzov Не мог бы ты привести кейсы когда модели нужно оставлять рядом со стораджем и оставлять зависимость хэндлера от стораджа?

  • @maxdzh212
    @maxdzh212 Před rokem +1

    Интерфейс который объявлен рядом с использованием нужно объявлять приватным, так как нет нужды ему быть публичным.
    И пример с использованием storage в слое транспорта выглядит не очень, так как это означает что бизнес логика находится либо в слое транспорта, либо в слое базы данных. Бизнес логика в транспорте это плохо, так как при смене транспорта придется логику переносить и в целом это нарушает high cohesion. Бизнес логика в слое базы данных даже хуже, потому что есть риск реализовать логику на языке sql, а при смене базы данных переписывать ее заново

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +1

      Хорошие замечания. На счет приватности интерфейса точно согласен.
      Остальное дискутивно, но звучит тоже справедливо.

  • @dmitriyobidin6049
    @dmitriyobidin6049 Před 9 měsíci +1

    Конечно в месте использования. Описывать интерфейсы в месте реализации - это где? Если структуры их реализуют неявно - то как понять где у нас место реализации? Сама задача невыполнима, не говоря уже о ее нелогичности.

  • @user-ju7xj3qu6k
    @user-ju7xj3qu6k Před 5 měsíci

    Я предпочитаю выносить интерфейсы в отдельный модуль и проектировать из так, чтобы они опирались только на интерфейсы и стандартные типы. Это позволяет модулям реализации и использования вообще не знать друг о друге.

  • @dimitrobest5293
    @dimitrobest5293 Před rokem +1

    камера закривает код, можно слева внизу разместить

  • @Michel_de_Montaigne
    @Michel_de_Montaigne Před 5 měsíci

    Кто читал совершенный код, заметит ещё одно преимущество в таком подходе.

  • @fprotimaru1944
    @fprotimaru1944 Před rokem

    Бро, попробуй New UI от Jetbrains

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +2

      Я пока морально не готов к этому))

  • @ViktorPolyakov15
    @ViktorPolyakov15 Před 8 měsíci

    А насколько бесплатны интерфейсы в гошке?

    • @nikolay_tuzov
      @nikolay_tuzov  Před 8 měsíci

      Не бесплатны - как в плане памяти, так и в плане быстродействия. А насколько, тут уже нужно разбирать конкретные случаи.
      Можете глянуть этот мой ролик, например: czcams.com/video/-cX0CqG6rgA/video.html
      Он шуточный, конечно! Но замеры в части про интерфейсы вполне честные. Шуточные там только выводы, которые я из этого делаю.

    • @ViktorPolyakov15
      @ViktorPolyakov15 Před 8 měsíci

      @@nikolay_tuzov Ага, спасибо за пример. А насчет видео по ссылке... Вот вы там шутили, а я сейчас работаю с людьми, которые именно так и думают на полном серьезе и переубедить их невозможно. Хорошо только одно - они работают в соседней команде.

    • @ViktorPolyakov15
      @ViktorPolyakov15 Před 8 měsíci

      @@nikolay_tuzov Спасибо за тест, только вот ссылки на его код я под видео не нашел. А насчет самого ролика... вы вот там шутите, а я работаю с людьми которые именно так и пишут код. Хорошо только одно, что они работают в соседней команде.

    • @nikolay_tuzov
      @nikolay_tuzov  Před 8 měsíci

      @@ViktorPolyakov15 бывает, я тоже с такими сталкивался =)

  • @andreipopov2700
    @andreipopov2700 Před rokem

    Видео по мокам +1

  • @somebodycrazy
    @somebodycrazy Před 3 měsíci

    Это конечно сильно... закрывать часть кода своим лицом. Спрашивается, для чего? Можно было бы окно с лицом сделать в два три раза меньше и этого было бы достаточно, или допустим включать иногда, в важных моментах. Некоторые вообще не выводят лица, что увеличивает объем рабочей области, за что благодарности авторам. Самое лучшее, это показать вначале, и в конце видео, вполне достаточно.

  • @iqMoreThatZero
    @iqMoreThatZero Před 7 měsíci

    Мы становимся не зависимым от storage.user? Ага. А то что мы отдаём storage.users.User ниче?

  • @user-qx3km6wp1p
    @user-qx3km6wp1p Před rokem

    Размещение интерфейсов в месте использования является правильным подходом и в c++ и в других подобных языках. Никакой специфики go в этом нет. Если для кого-то это кажется странным, возникает большой вопрос к его профессионализму

  • @batpyiiikob7245
    @batpyiiikob7245 Před 6 měsíci

    Спасибо!

  • @ThePirateHistory
    @ThePirateHistory Před 6 měsíci

    Видос досмотрел, так как видел анотацию в видео про url-shortnere, а в чём проблема чтобы создать не целый объект Users, а тот же ЮзерКреайте, и не нужно будет создавать все методы, хотя странно раз ты меняешь хранилище, то по идеи нужно переписывать всё, а если лишь просто часть заменить, не большие куски, то можно их ведь вынести

  • @georgiy_kulagin
    @georgiy_kulagin Před rokem +3

    Пишу комментарий про строчку go:generate :)

    • @nikolay_tuzov
      @nikolay_tuzov  Před rokem +4

      Предыдущему товарищу ответил, продублирую))
      Копать сюда: eli.thegreenplace.net/2021/a-comprehensive-guide-to-go-generate/
      Как доберутся руки, сделаю об этом отдельный видос

    • @georgiy_kulagin
      @georgiy_kulagin Před rokem

      @@nikolay_tuzov спасибо