Dependency Injection, С#, Внедрение зависимостей, unity, gamedev

Поділитися
Вставка
  • Опубліковано 7 чер 2024
  • Если будут вопросы
    мой тг @wargy
    моя почта kazancev.s215@gmail.com
    Автору на кофе и шаурму
    4276 5500 5792 8742 - карта Сбербанка
    Тайминги
    00:00 Введение
    00:30 Дисклеймер
    01:28 Проблема зависимостей
    02:06 Пример проблемы из геймдева
    03:25 Плохое решение №1: попытка пофиксить увеличением методов
    04:10 Плохое решение №2:, попытка создать разные классы
    04:55 Пример проблемы, анализ слабых мест в коде
    05:52 Dependency Injection, главное
    06:40 Dependency Injection, схема
    07:30 Масштабирование Dependency Injection
    08:08 Возвращаемся к коду, рефакторим Player
    08:50 Возвращаемся к коду, пишем Injector
    09:22 Виды Dependency Injection
    10:24 Inversion of Control, Инверсия потока управления
    12:09 Плюсы и минусы паттерна Dependency Injection
    14:19 Финал
  • Ігри

КОМЕНТАРІ • 88

  • @sergeykazantsev1655
    @sergeykazantsev1655  8 місяців тому +4

    Ребятушки, многие из вас писали по поводу непоняток в коде, чаще всего выбора CalculatorType и тд. Демо код из видео я немного переделал и превратил в небольшую игрульку, выложил её на гитхаб
    С ней ознакомиться можно здесь
    github.com/Haywaar/PatternDemoStorage/tree/main/Assets/Patterns/DIExample

    • @botcser
      @botcser 4 місяці тому

      Спасибо.
      1. DI может решить проблему динамического изменения зависимости в процессе (изменить калькулятор урона в процессе игры)?
      2. Метод "Construct" у Player - причины названия? Это личное или кто-то из умных дядек так советует? (из СИ я привык к Init)
      ПС: раздел "Dipendency Injection, главное" 5:52 - 6:39 (7:29) сильно сбивает с толку, понимание смысла DI распыляет, размазывает, я этот раздел просто пропускаю, ничего не теряя в понимании... Раздел "Inversion of Control, Инверсия потока управления" - вот главное, и по мне, должно идти вначале, как раз до 5:52 или вместо, потому что именно оно является основой DI и объясняет принцип DI :*

  • @themesdaly7598
    @themesdaly7598 Рік тому +7

    Автор ты лучший) Прошерстил разные видосы на эту и подобные темы, твоя подача самая внятная и простая. "Сложное сделать просто, а простое сделать сложно" Респект

  • @ivan-jc1bp
    @ivan-jc1bp Рік тому +7

    Отличная подача. Зря в колледж пошёл, нужно было по вашим видео учиться. Как всегда очень круто! Спасибо.

  • @user-gp7js3zu6b
    @user-gp7js3zu6b Рік тому

    Вау!!! Зашло)) для меня оооочень полезная инфа, т. к. сейчас копаюсь в Spring и Angular. Спасибо огромное)

  • @user-or7jq2ec8b
    @user-or7jq2ec8b 9 місяців тому

    Всё было крайне понятно! Большое спасибо!

  • @hi-techmexanik2567
    @hi-techmexanik2567 4 місяці тому

    Отличный канал) хорошо объясняешь. Обычно не оставляю комментарии но тут не смог пройти мимо

  • @vitalysushilov5802
    @vitalysushilov5802 2 місяці тому +1

    Спасибо. Отличный канал, отличное изложение материала.

  • @cnfnbcn3227
    @cnfnbcn3227 21 день тому

    Орнул с Rabotyaga injection)))
    Спасибо за видео!

  • @LEVON007100
    @LEVON007100 10 місяців тому

    Ты лучший, невероятно понятные видео ❤

  • @scorp9838
    @scorp9838 Місяць тому

    во, то что надо! целый плейлист с паттернами👍👍

  • @it_is_muchomor
    @it_is_muchomor Рік тому +1

    Спасибо тебе, хороший человек.

  • @-unity-
    @-unity- 5 місяців тому +1

    Огромная благодарность! Отдельное спасибо за неторопливую подачу материала. А то складывается ощущение, что люди пытаются впихнуть весь материал своего ролика в 60 секунд, поэтому тараторят что-то там неразборчивое.

  • @ephitariathegame2brainstud996

    Лайк, подписка. Четко, интересно, понятно. Спасибо!

  • @MsTroll2011
    @MsTroll2011 2 місяці тому

    Очень интересный урок! Подписываюсь на ваш канал

  • @user-yu9wr7tt9v
    @user-yu9wr7tt9v Рік тому

    Какой же божественный канал, того глядишь стану гейм девелопером

  • @priznak6808
    @priznak6808 3 місяці тому

    Большое спасибо за видео! все понятно

  • @alexanderivanov9160
    @alexanderivanov9160 3 місяці тому

    Лучший урок из тех что я видел

  • @ProgrammerFlunt
    @ProgrammerFlunt 3 дні тому

    очень круто!

  • @kardonov
    @kardonov 26 днів тому

    Со всем изложенным полностью согласен 👌

  • @user-sq4ff4zp9b
    @user-sq4ff4zp9b 11 місяців тому

    Подписка! Однозначно)

  • @Slaxap
    @Slaxap 11 місяців тому +1

    Интересное видео. Спасибо. Но я порекомендую добавить побольше устного и визуально дотошного объяснения. К примеру: Где плюсы "Удобен на проектах среднего и большого размера" - потому что: *И тут объясняешь" (Даже если ты говорил это раньше, повторение является хорошим закрепление материала)

    • @sergeykazantsev1655
      @sergeykazantsev1655  11 місяців тому +1

      Интересная рекомендация :) Я наоборот себя постоянно фильтрую и стараюсь не растекаться мыслью по древу, а тут получается есть желающие еще больше подробностей и объяснений) Подумаю :)

  • @thebiggestdick69
    @thebiggestdick69 Рік тому

    еще интересно было бы послушать про DI контейнеры и в частности Zenject

  • @313Eugene
    @313Eugene 7 місяців тому

    Спасибо 👍🏻

  • @mxustin
    @mxustin 6 місяців тому

    Бро! Ты лучший

  • @user-bg3ol8wx8i
    @user-bg3ol8wx8i 8 місяців тому

    Спасибо за ролик, супер! Даёшь ZENJECT!!!

  • @rustamergashev7278
    @rustamergashev7278 4 дні тому

    👍

  • @golodnenkiy
    @golodnenkiy 11 місяців тому

    Спасибо за видео) Вопрос: Если вместо интерфейса, сделать абстрактный класс с абстрактным методом и все виды расчета урона прописывать в классах наследующих его и в injector-е прокидывать зависимость с помощью UpCast-а , это все еще будет паттерн Dependency Injection?

    • @sergeykazantsev1655
      @sergeykazantsev1655  11 місяців тому +1

      Да, мне кажется тут не важно, внедряете ли вы его как интерфейс или как абстрактный класс, по структуре, раз вы можете вставить туда разные реализации, UpCasе-я их как базовый класс - всё ок. В DI нет строгого правила - ВНЕДРЯЙТЕ ТОЛЬКО ИНТЕРФЕЙС. Абстрактный класс я думаю что тоже пойдет

  • @mikki5923
    @mikki5923 10 місяців тому

    Скажу лишь, что DI использую интуитивно.
    У меня что-то вроде правил.
    1. Делай все зависимости на интерфейсах;
    2. Пихай все зависимости в Инжектор;
    3. Инжекть через конструктор, если не MonoBehaviour, если MonoBehaviour, то через [Inject], либо специальный метод а-ля Init(VContainer);
    Это моё такое "понимание" DI, другие разработчики вроде на такую мою последовательность не жалуются.
    Надо будет пересмотреть видео еще раз. Реально, если говорить за теорию, то даже с наличием практики было тяжко сразу всё понять и запомнить:3

    • @sergeykazantsev1655
      @sergeykazantsev1655  10 місяців тому

      Да, я приблизительно так же DI понимаю.

  • @icecril8677
    @icecril8677 14 днів тому

    спасибо

  • @ziiron322
    @ziiron322 Рік тому

    Классный канал! А разбирать зенжект будем? Или быть может екс?

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому

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

  • @mikki5923
    @mikki5923 10 місяців тому

    Проблема Singleton-ов стоит в том, что GC не чистит статические данные, так как они будут существовать всю продолжительность жизни программы.
    Вот поэтому Singleton это антипаттерн. Он тупо засирает память на больших и средних проектах.
    + Тестирование слабое и нарушение SRP;
    Насчёт минуса DI: "Тяжелее дебажить".
    Это так при условии, что у вас 1 DI контейнер. В проекте АА и ААА мы, создаем сразу несколько контейнеров которые очень сильно напоминают работу Assembly Definition(визуально).
    Это очень похожий принцип, того как в книге "Level Up Your Code" от Unity изобразили паттерн Observer, где для его улучшения создают EventManager.
    Спасибо за видео, подтянул теорию.

  • @forcesoftheevil9252
    @forcesoftheevil9252 Рік тому

    Пример отлично подобран! В начале я не понял, почему бы не сделать в пример какой-нибудь Input(базовый класс), а в каком-нибудь контроллере уже заменять на KeyboardInput, MobileInput и т.д.

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому +1

      Да, на практике чаще всего клавиатура самый очевидный сервис, но я решил что пример с сервисом расчёта урона более наглядный будет, ибо можно всё пощупать и посмотреть сразу же

    • @user-zs8nt8yk4e
      @user-zs8nt8yk4e Рік тому

      @@sergeykazantsev1655 а подскажите пожалуйста такой момент. вы говорили что с ДИ код будет меньше без свитчей и тд. А потом когда показали код на 9.15 там и свич кейсы есть, и куча классов дамаджКалькуляторРендж... как показалось кода, стало больше, запутанней...
      мы прекрасно обходились классами. чет вообще не понял что же изменилось...

    • @user-co8vr7xp7o
      @user-co8vr7xp7o Рік тому

      @@user-zs8nt8yk4e потому что на 9.15 тайминг показан Injector, который а) может быть похожим но чуть другим в плане реализации, а именно быть фабрикой (Factory) и реально в рунтайме по типу (type) или другим задачам - инстанциировать конкретный экземпляр DamageCalculator, и всеравно такой switch (type) будет, главное что он в Factory а не внутри Player (который не должен знать в данной задаче, впрочем может быть и другая задача и тогда Player будет не в конструкторе получать а скажем внутри иметь Weapon и от Weapon уже будет зависеть какой Calculator у этого оружия); или (б) это может быть статичный выбор зависимости (без switch, без решения подтипа) когда "геймдиз прототипирует" и тогда везде в конструкторы пойдет одинаковый инстанс (или одинаковый подтип инстанса) скажем SimpleDamageCalculator; p.s. а кода будет полюбому больше за счет Factory (и выбора) или даже за счет Interface-ов, это минус паттернов такого типа

    • @user-zd3qw7le5c
      @user-zd3qw7le5c Рік тому

      плохо что нет целостного кода

    • @sergeykazantsev1655
      @sergeykazantsev1655  9 місяців тому

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

  • @Lucio11a
    @Lucio11a 11 місяців тому

    Даа... синглтон, где прокиданы все зависимости... знакомо :D
    Кстати, а что на счет ECS?))

    • @sergeykazantsev1655
      @sergeykazantsev1655  11 місяців тому +2

      Мне пока не хватает компетенции чтобы про ECS рассказать так как ручками я его никогда не трогал и знаю только теорию. Но когда-нибудь я до него доберусь :D

  • @ilyainjustus5324
    @ilyainjustus5324 Рік тому

    а это нормально что в обновленном Player в Attack мы не передаем CalculatorType? Для простоты было сделано?)

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому

      CallculatorType в плеер не целесообразно передавать именно потому, чтобы Player не распухал. DI позволяет эту проблему распухания обойти. Решение с CalculatorType для метода Attack является плохим, на 04:25 можно посмотреть. На 08:28 есть сравнение старого и нового правильного плеера. Таким образом CalculatorType нам не нужен в методе Attack если мы с калькулятором работаем на уровне интерфейса)

  • @MrDudeNudem
    @MrDudeNudem Рік тому

    9:16 тут разве нет нарушения открытости-закрытости? И ещё вопрос, а если у нас текущий урон задаётся на уровне конфигурации, то при смене типа урона(а он будет меняться достаточно часто, насколько понимаю) не придется ли переконфигурировать приложение заново?

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому

      Я не до конца понимаю о нарушении OCP в каком именно классе вы имеете ввиду. Если о DamageCalculatorRange - то в нём я не вижу нарушения OCP. Если вы говорите об Injector-е, то да, если у нас постоянно будут добавляться новые калькуляторы, switch-case будет расти. Но все равно где-то должен быть класс который будет связывать конфиги и конкретные классы, скажет - "Если нам нужен урон с перепадом, надо использовать DamageCalculatorRange"

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому

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

    • @MrDudeNudem
      @MrDudeNudem Рік тому

      @@sergeykazantsev1655 Да, именно про свитч кейс говорил. Спасибо за видосы, очень круто сделанные! :)

  • @user-yz6jr9or3u
    @user-yz6jr9or3u 6 місяців тому

    Здравствуйте! Вот вроде понял суть, но вообще не понял его отличие от паттерна стратегии. Можно пояснить? Желательно с примерами.

    • @sergeykazantsev1655
      @sergeykazantsev1655  6 місяців тому

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

  • @scc-6
    @scc-6 13 днів тому

    Вот ты ебать красиво стелишь, приятно слушать!

  • @user-dv2pm3id9f
    @user-dv2pm3id9f 11 місяців тому

    А каким образом мы передаём тип калькулятора в Init?

    • @sergeykazantsev1655
      @sergeykazantsev1655  11 місяців тому

      В Init тип калькулятора приходит сверху и уже не так важно как именно. Тип калькулятора может прилетать по разному: с сервака/JSON-а/ScriptableObject-а. Наша главная задача обработать команду "Я хочу калькулятор А, выбери нужную логику обработки и расчёта". Ту самую нужную логику обработки и расчёта реализует Injector. Кто именно отправляет команду - там не важно
      Блин, походу надо написать демку, а то много таких вопросов поступает)

  • @omegakrakengames
    @omegakrakengames Рік тому +1

    Таких каналов в русском сегменте можно по пальцам одной руки пересчитать буквально

  • @Nikita-os6om
    @Nikita-os6om 3 дні тому

    Очень напоминает паттерн стратегия, в чем их ключевая разница?

    • @sergeykazantsev1655
      @sergeykazantsev1655  3 дні тому +1

      В масштабе и области применения, как мне кажется. DI это паттерн который объясняет как строить архитектуру. Стратегия это паттерн основанный на di, предназначенный для реализации разных способов выполнения одной и той же задачи

  • @jackmusic631
    @jackmusic631 8 місяців тому

    я что-то не догоняю откуда вызывается в Injector метод Init и берутся параметры CalculatorType

    • @sergeykazantsev1655
      @sergeykazantsev1655  8 місяців тому

      Да, в видео это я не объяснил, потому написал в открытом гите демку
      github.com/Haywaar/PatternDemoStorage/tree/main/Assets/Patterns/DIExample
      Injector является точкой входа - то есть стартовым скриптом который запускается в самом начале игры.
      Параметры CalculatorType берутся на основе стартовых конфигов - сейчас мы в самом Injector-е в инспекторе выбираем один из вариантов.
      Подразумевается что выбор того или иного калькулятора основан на конфигах которые прилетают нам откуда-то снаружи(условно гд потрогал настройки на сервере и мы их подтянули)

  • @user-tj6bp4ec4u
    @user-tj6bp4ec4u Рік тому

    А как player понимает тип атаки ? Нигде же не передается тип атаки

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому +1

      09:00. Player не знает с каким типом атаки он работает, ему это не нужно. О типе атаки знает Injector. Он помещает в Player какой-то тип калькулятора, а Player работает с калькулятором на уровне интерфейса и может не знать с какой конкретной реализацией он работает. В этом и есть идея DIP.

  • @TikhonovGleb
    @TikhonovGleb 9 місяців тому

    @sergeykazantsev1655 в рассказе про DI вы никак не упомянули DI-контейнер. Поэтому вопрос, можно ли считать, что класс-injector в вашем примере - это и есть DI-контейнер?

    • @sergeykazantsev1655
      @sergeykazantsev1655  8 місяців тому +1

      Я бы сказал так. DI-контейнер это и есть Injector. У обоих задача - прокидывать зависимости в классы через интерфейс. Но обычно под DI-контейнером подразумевается более сложная сущность, некий Injector на максималках или же прокачанный Injector.
      Задача Injector-а - внедрить зависимости в классы через интерфейс.
      Задача DI-контейнера - выбрать/сгенерировать зависимости и внедрить их в классы через интерфейс. В DI контейнере может быть много внутреннего функционала - фабрики для создания сервисов, контроль за тем, нужен ли кому-то сервис или можно его отрубить чтобы в памяти не висел, подкапотная логика прокидывания зависимостей как в Zenject-е, чтобы ты не ручками зависимости прокидывал а просто бахнул тэг [Inject] и оно само прокинулось и так далее.
      Так что в моём примере можно сказать что Injector это и есть DI-контейнер, только этот контейнер жутко урезанный и ограниченный

  • @beziboba9458
    @beziboba9458 2 місяці тому

    Сейчас DI даже с джунов спрашивают 😢

    • @sergeykazantsev1655
      @sergeykazantsev1655  2 місяці тому

      Да, к сожалению, требования подросли

  • @user-zd3qw7le5c
    @user-zd3qw7le5c Рік тому

    очень было бы хорошо если бы вы показали весь код чтобы юзеры могли его запустить на своих ПК

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому +1

      У меня на канале есть рубрика "Паттерны на практике" где я пишу простые игры и выкладываю их на гитхаб и на примере игр показываю решения. Сейчас есть одна игра, там нет DI, он будет во второй игре, когда я до неё доползу :) Если кирпич на голову не упадёт через полтора-два месяца выложу игру)

    • @user-zd3qw7le5c
      @user-zd3qw7le5c Рік тому

      @@sergeykazantsev1655 спасибо . . . но она вроде как на Unity, а гораздо больше юзеров работают с WinForms . .. поэтому желательно на них чтобы была игра.

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому

      Ну на WinForms я к сожалению не смогу написать игру, ибо я чистый юнитолог и пишу только на юнити :(

    • @user-zd3qw7le5c
      @user-zd3qw7le5c Рік тому

      @@sergeykazantsev1655 если вы юнитолог тогда подскажите в какой среде разработки пишется обработка графики . . . с кодом понятно - визюал студия . . . а графика в какой среде пишется ? . . . и подскажите, пожалста, какое видео смотреть чтобы с нулю начать обучаться юнити

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому

      Юнити это и игровой движок и среда, в ней как в редакторе вы размещаете сцены и объекты и в ней же вы подключаете написанный код как некоторые компоненты. Насчёт курсов по юнити с нуля, затрудняюсь ответить, сам в свое время купил курс на юдемии 6 лет назад, но за это время многое могло измениться

  • @user-uv6zs1xe1g
    @user-uv6zs1xe1g 6 місяців тому

    di как паттерн ничего общего не имеет с принципом на буковку D, никто не запрещает в di использовать конкретные реализации и поставлять их клиентам, то что di может внедрять конкретную реализацию через интерфейс - это следствие. Был как раз упомянут service locator, там тоже всё прекрасно, есть инстансы, есть интерфейсы и при этом есть возможность получать зависимости в виде интерфейса, но проблема была в том, что в классической реализации локатора клиенту поставлялся этот мешок с зависимостями и не понятно было что в нём содержится, а если потребовать такой интерфейс выдаст ли он мне нужный и тому подобные вещи, а ведь буковка D соблюдается при таком подходе - никаких конкретных реализаций, только АБСТРАКЦИИ. Основное что нужно понимать, что в вашей программе при таком подходе появляется ровно одна точка, где разрешаются ЗАВИСИМОСТИ(не важно от чего, хоть от инта) и уменьшаете то количество мест, где вручную нужно было создавать и разрешать зависимости, с таким подходом вы пишете код и перестаёте думать о том как вам придёт эта зависимость или как и где её опрокинуть(хотя наивно так тоже думать), и тем самым вы больше добиваетесь прозрачности в потоке выполнения программы, чем пытаетесь соблюдать какой-то принцип на букву D. Поэтому с лёгкостью можно создавать фреймворки для таких штук, но также стоит упомянуть, что в таком случае вы отдаёте контроль над выполнением вашей программы другому инструменту, что также может сказаться в дальнейшем, но это уже больше детал

    • @sergeykazantsev1655
      @sergeykazantsev1655  6 місяців тому

      1. "DI как паттерн не имеет ничего с DIP" - к сожалению я с этим не могу согласиться. Очень важной частью DI как паттерна является внедрение зависимостей на уровне ИНТЕРФЕЙСА. А DIP говорит об организации кода на уровне АБСТРАКЦИЙ. Я уже не говорю о том что практически в любом материале по DI тебе в связку накидывают материалы про IoC который напрямую связан с DIP.
      2. Можно ли использовать DI без интерфейса и прокидывать зависимости напрямую как конкретные реализации? Да, конечно. Но я бы разделял DI как паттерн(внедрение зависимостей на уровне интерфейса) и DI как простое прокидывание одних классов в другие. Если из DI убрать вот эту часть про "на уровне интерфейса" - что от него останется? Идея собирать зависимости в одном месте? А чем это отличается от какого-нибудь Entry Point да или тот же SRP можно сюда притянуть.
      Лично я не считаю простое прокидывание одних классов в другие паттерном, так же как не считаю что Фабрика - это паттерн. Абстрактная фабрика или фабричный метод - это паттерны проектирования. Фабрика - это класс который порождает объекты но в этом нет никакого шаблонного решения. Возможно вкусовщина

    • @user-uv6zs1xe1g
      @user-uv6zs1xe1g 6 місяців тому

      @@sergeykazantsev1655 Понимаете, то что вы называете присуще и сервис локатору, основная идея DI, что у вас появляется точка конфигурации вашего приложения, вы не размазываете конфигурацию по приложению, а собираете всё в одном месте. Объект перестаёт думать о зависимостях и как ему их получить, он либо их разрешает сам, либо делегирует это слою инициализации приложения(что в народе и зовётся entry point). Насчёт последнего абзаца, это и есть основная идея DI, зависимости в классе настраиваются в каком-то инжекторе или контейнере или каким-то фреймворком. Класс перестаёт думать как ему получить ту или иную зависимость, он просто перестаёт отвечать за это. А программировать на уровне интерфейсов это уже совсем другое, если класс зависит от абстракции, то ему и поставим конкретную реализацию под абстракцией, которую если что можно поменять в той самой точке приложения и не думать, а в каких ещё местах надо было это сделать.
      В общем, мне просто не нравится что в DI начинают рассказывать следствия этого подхода, DI - это про получение зависимостей, то что вы описываете в ролике это ioc-контейнеры. Тут же важно понимать само действие, классу их поставляют или он сам их запрашивает или вообще сам их создаёт.
      И про первый пункт, в этом и проблема, что рассказывают про ioc контейнеры, а не про DI как таковой. Как и говорил выше, ioc контейнеры это конкретная реализация принципа DI, но не DI как таковой. Просто часто наблюдаю ситуации, когда говорят про DI и сразу ответ, а это какой-то ioc-контейнер с именем X.

    • @user-uv6zs1xe1g
      @user-uv6zs1xe1g 6 місяців тому

      @@sergeykazantsev1655 Также стоит упомянуть, что в ролике вы рассказываете про проблему сильной связности, DI к этому отношение не имеет.

    • @sergeykazantsev1655
      @sergeykazantsev1655  6 місяців тому

      Ну я думаю что мы друг друга услышали но остались при своём мнении. Наверное можно назвать это вкусовщиной потому что разные источники будут говорить разное.
      С моей точки зрения ключевая идея DI именно в внедрении зависимостей на уровне интерфейса. Сервис локатор выполняет схожие задачи но несколько другим образом, вы это знаете
      Я не считаю что главная идея DI - "у вас все зависимости должны быть собраны в одном месте". Таким местом(классом) в которым создаются зависимости EntryPoint-ы да и тот же сервис локатор на этапе инициализации.

  • @thebiggestdick69
    @thebiggestdick69 Рік тому

    Не совсем понял разницу IoC и DIP
    Судя по всему это одно и тоже с разными названиями

    • @sergeykazantsev1655
      @sergeykazantsev1655  Рік тому

      IoC появился как следствие DIP. Можно сказать что IoC это часть DIP. IoC - это про поток управления, классы высокого уровня теперь не зависят от классов низкого уровня. DIP более широкое понятие, которое говорит не только про инверсию потока управления, но и про зависимость от абстракции

  • @0ziver
    @0ziver 5 місяців тому +1

    Вообще DI нарушает приципы solid и создает огромную путаницу в коде. Чем больше зависимостей добавляешь тем хуже, странный подход со стороны продакшенов.

    • @sergeykazantsev1655
      @sergeykazantsev1655  5 місяців тому +1

      А в чем именно, с вашей точки зрения, di нарушает solid?

    • @0ziver
      @0ziver 4 місяці тому

      2,3,4 принципы. Так же, использование di и рядом не стоит с KISS/DRY. Так же, с моей точки зрения ООП идет нога в ногу с SOLID. Классы доджны быть инкапсулированы в ООП и иметь единую ответственность по SOLID?, но если мы будем что-то пытаться засунуть в закрытый класс, который должени иметь свою зону отвествунности через DI, мы просто теряем смысл писать на ООП и под SOLID. DI отлично в ECS системах впишется. А большинство потребностей "Внедрения зависимостей" решаются прямыми руками и использованием делегатов. Но может я и не прав.@@sergeykazantsev1655

    • @sergeykazantsev1655
      @sergeykazantsev1655  3 місяці тому +1

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

    • @leonwew
      @leonwew 24 дні тому

      Наоборот! DI это вся суть ооп и солида. Просто при прокидывании зависимостей ты должен привязываться не к конкретным реализациям, а к абстрациям. Это тебе дает огромную силу и гибкость. Процесс тестирования упрощается в разы.