SOLID принципы: DIP (Принцип инверсии зависимостей (The Dependency Inversion Principle)

Поділитися
Вставка
  • Опубліковано 2 чер 2024
  • SOLID принципы: DIP (Принцип инверсии зависимостей (The Dependency Inversion Principle) Зависимость на Абстракциях. Нет зависимости на что-то конкретное
    Курсы для новичков:
    JAVA - bit.ly/3kQBcZT
    JAVA Start - bit.ly/3fZYnxi
    Инструментарий JAVA - bit.ly/3h5nBvr
    Automation QA (Java) - bit.ly/2YcexgS
    ANDROID - bit.ly/2PXUPkH
    C#/.NET - bit.ly/312xmoA
    C# START - bit.ly/2CE1XzE
    PYTHON - bit.ly/3g4F0TK
    FRONT-END - bit.ly/3iLNjFV
    WORDPRESS Developer - bit.ly/2Fv6eGx
    SALESFORCE Developer - bit.ly/3h6p198
    UI/UX дизайн - bit.ly/2E0hb2w
    Project management - bit.ly/2E2mazB
    Обучение на проекте - bit.ly/349pGCY
    Продвинутые курсы для состоявшихся девелоперов:
    GRASP and GoF Design patterns - bit.ly/2E7oo0q
    Enterprise patterns - bit.ly/3kQBIah
    Сайт Foxminded: bit.ly/2DZtV9u
    Foxminded в ФБ: / foxmindedco
    FoxmindEd в Instagram: / foxminded.ua
    Foxminded в VK: foxminded
    Мой Telegram: t.me/nemchinskiyOnBusiness
    Мой блог: www.nemchinsky.me
    1. На основе работы Роберта Мартина (дяди Боба). Акроним SOLID предложен Michael Feathers
    2. SOLID (сокр. от англ. single responsibility, open-closed, Liskov substitution, interface segregation и dependency inversion)
    1. SRP Принцип единственной ответственности (The Single Responsibility Principle) - Каждый класс должен иметь одну и только одну причину для изменений.
    2. OCP Принцип открытости/закрытости (The Open Closed Principle) - программные сущности … должны быть открыты для расширения, но закрыты для модификации
    3. LSP Принцип подстановки Барбары Лисков (The Liskov Substitution Principle) объекты в программе должны быть заменяемыми на экземпляры их подтипов без изменения правильности выполнения программы
    4. ISP Принцип разделения интерфейса (The Interface Segregation Principle) много интерфейсов, специально предназначенных для клиентов, лучше, чем один интерфейс общего назначения
    5. DIP Принцип инверсии зависимостей (The Dependency Inversion Principle) Зависимость на Абстракциях. Нет зависимости на что-то конкретное
    0:00 - вступление Сергея Немчинского
    0:24 - формулировка The Dependency Inversion Principle (DIP)
    0:55 - все принципы SOLID и место принципа инверсии зависимостей среди них
    2:35 - как следовать принципу DIP
    8:10 - про soft code, hard code и DIP

КОМЕНТАРІ • 197

  • @asdclip
    @asdclip 3 роки тому +66

    Здравствуйте, Сергей. По поводу DIP, небольшое уточнение, если у вас высокоуровневый модуль A зависит от низкоуровнего модуля B и вы вынесете в модуле B интерфейс и теперь у вас A зависит от интерфейса модуля B, то это не будет DIP а скорее OCP. У вас как модуль A зависил от модуля B, так и зависит, только теперь от интерфейса. Смысл DIP - это инвертирования зависимостей без инвертирования потока управления. Поэтому интерфейс для B нужно объявлять в модуле A и получаем теперь, что А зависит только от своего интерфейса. а B уже зависит от А (зависимость инвертирована). Этот подход служит часто для изоляции одних слоев приложения от других, например доменного слоя от инфраструктуры.

    • @cannibalirk3055
      @cannibalirk3055 Рік тому +13

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

    • @user-cp3rd9zd3x
      @user-cp3rd9zd3x Рік тому +3

      Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций.

    • @tee-hee
      @tee-hee Рік тому

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

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

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

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

      Ребят, уже прошло три года с момента написания ваших комментов. Надеюсь, вы уже поняли, что ОН ВСЕ правильно говорит? ))
      Человек, показывая на пальцах, просто вводит в курс дела. А для того, чтобы действительно понять, что же такое DIP, нужно будет написать парочку рабочих приложений и только тогда приходит настоящее понимание того, что это, как это все работает и как использовать Dependency Injection, IRepository, Repository, CQRS, Clean Architecture и как все это и создает Dependency Inversion.

  • @veryaev
    @veryaev 3 роки тому +188

    Спасибо за видео, все очень понятно!
    Пока всего два вопроса!
    1) Как вас зовут?
    2) Большой ли у вас стаж в программировании?

  • @writetoyourdestiny
    @writetoyourdestiny 3 роки тому +147

    Здравия, Сергей, хотелось бы услышать от вас про unit-тестирование, в частности про: Spy, Mock, Stab и еще вроде Fake.

    • @aerahtv0000
      @aerahtv0000 3 роки тому +1

      про mock и stub вроде было квкое-то видео, поищи на канале

    • @alekseytsvetaev6261
      @alekseytsvetaev6261 3 роки тому +1

      Да хотелось бы послушать

    • @eduardmart1237
      @eduardmart1237 3 роки тому +1

      Поддерживаю

  • @Redux-lv6vu
    @Redux-lv6vu Місяць тому

    Большое спасибо за ваши видеоролики

  • @P1oN4ik
    @P1oN4ik 3 роки тому

    Спасибо! Очень крутой цикл роликов. обязательно скину друзьям.

  • @user-uf9kn1lg2s
    @user-uf9kn1lg2s 3 роки тому +3

    Спасибо большое за видео!

  • @andyvoice
    @andyvoice 3 роки тому +55

    за СОЛИД и двор, лайк в упор

  • @user-yo3et1dy2g
    @user-yo3et1dy2g Рік тому +1

    поддерживаю. Тема тестирования очень актуальна. Хочется получить информацию в присущей для вас доступной манере подаче информации

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

    Спасибо за видео!

  • @user-bq8os7dr8s
    @user-bq8os7dr8s 2 роки тому +1

    Спасибо, весь курс хорош)

  • @simplechannel7859
    @simplechannel7859 2 роки тому

    Еще даже не посмотрел видео, а уже поставил лайк. Надо завязывать с такой привычкой

  • @dgavrikov84
    @dgavrikov84 3 роки тому +2

    C наступающем Новым Годом, Сергей. В целом с вами согласен, с единственной оговоркой. Использовать класс через интерфейс нужно при внешнем взаимодействии к этому классу, если понимаете о чем я. Если класс реализует обертку настроек или DTO то не вижу смысла этого делать.

  • @TeuFortMan
    @TeuFortMan 2 роки тому

    Доходчиво и достаточно коротко!

  • @alexkononenko4862
    @alexkononenko4862 3 роки тому

    Сергей, все правильно, так и пишем, несогласных стараемся убедить :)

  • @juliusmalkov9620
    @juliusmalkov9620 3 роки тому +38

    а можно видео потом про DI & IoC?

  • @user-bt9hx3ik6e
    @user-bt9hx3ik6e 3 роки тому +7

    хорошие лекции, спасибо за ваш труд.

  • @user-jg9ci7be5x
    @user-jg9ci7be5x 2 роки тому

    Спасибо! Все понятно.

  • @aradox4516
    @aradox4516 3 роки тому +1

    Вовремя открыл ютуб (5 сек назад залито). Спасибо за видео.

  • @feoktant
    @feoktant 3 роки тому +4

    Вот когда появится задача добавить авторизацию, в ИДЕ есть кнопка Extract Interface на классе, и делается дальше всё что вы рассказали.

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

    После размышлений на эту тему я возможно понял суть, но мое умозаключение отличается от того что вы написали выше - как я понял dep-inversion - это не БУКВАЛЬНЫЙ разворот зависимости в противоположную сторону, а её трансформация. Классы низкого уровня реализуют единый интерфейс, в свою очередь параметр(который и представляет зависимость) конструктора класса высокого уровня реализует тот же самый единый интерфейс. Таким образом, какой бы аргумент(зависимость) мы бы не кинули в конструктор, пока аргумент отвечает интерфейсу - класс будет работать. В итоге теперь класс высокого уровня ЗАВИСИТ не от класса низкого уровня, а от интерфейса в конструкторе. В свою очередь классы низкого уровня ТОЖЕ ЗАВИСЯТ от интерфейса. Это значит, что изменения в классе низкого уровня не соответствующие интерфейсу, который связывает его с классом высокого уровня, повлекут за собой изменения этого интерфейса, которые в свою очередь повлекут и изменения в коде класса высокого уровня(Ведь его параметр конструктора ТОЖЕ реализует этот интерфейс). Поэтому считаю конкретно это предложение из коммента выше неверным и вредным для новичков которые его читают: "если мы будем что-то менять в UserRepository, или мы можем изменить имя класса, а можем вообще унаследовать другой класс, то это никак не затронет UserClient , нам не нужно вносить изменения в его код". А в сам пример с UserClient и UserRepository я бы для того, чтобы показать именно суть добавил бы класс UserRepository2, который тоже реализует интерфейс IUserRepository, но по-другому(возможно с другой логикой) - и тогда класс UserClient мог бы работать и с UserRepository и с UserRepository2, и как раз при изменении зависимости, то есть самого передаваемого аргумента в конструкторе код в классе UserClient менять бы НЕ ПРИШЛОСЬ, так как для него UserRepository и UserRepository2 это по сути одно и тоже, но под капотом разное. Вот и получается, что теперь UserClient плевать с каким классом работать, вот только полной независимости от классов низкого уровня он все-таки не получил, по причине того, что при любом изменении в IUserRepository придется менять код в классе UserClient. Надеюсь верно и более-менее понятно написал. Если есть реально шарящие люди в этой теме, то надеюсь отпишут хоть что-то в ответ, так как я новичок и с этой темой поломал уже голову некоторое время чисто из-за того что все пишут, что если применить dep-inversion, то можно менять внутренности более низкоуровневых модулей не парясь об высокоуровневых, так вот я реально голову сломал пытаясь понять - как же они не будут влиять, если они от ОДНОГО ИНТЕРФЕЙСА ЗАВИСЯТ.

  • @gomer3894
    @gomer3894 3 роки тому +1

    спасибо за видео, поддержите видео комментариями!

  • @dmitriygordievskiy493
    @dmitriygordievskiy493 3 роки тому +3

    Спасибо, посмотрев видео наконец-то понял SOLID. В других источниках с которыми сталкивался либо слишком абстрактно пояснено, либо заумно.

    • @HATCOH4
      @HATCOH4 3 роки тому +2

      Че ты там понял?

  • @v.oleynik8282
    @v.oleynik8282 2 роки тому

    ПРОСТО ТОП!! СПАСИБО!!

  • @evgenykuksov6221
    @evgenykuksov6221 2 роки тому +2

    Бля, просто в душу поразила ваша манера объяснять! Так иногда не хватает грубых слов в общении/объяснении, потому что благодаря им в разы быстрее понимается!) Мое почтение за формат)

  • @ivanivanovq2964
    @ivanivanovq2964 3 роки тому +10

    Наконец послушал про "d". Роберт Мартин в своих лекиях про солид обычно рассказывает только про "sol"

  • @user-cw5gp8lu4e
    @user-cw5gp8lu4e 3 роки тому +4

    Расскажите пожалуйста про самые интересные, на ваш взгляд, принципы, которые описывал Роберт Мартин по мимо принципов SOLID

  • @z1zzz
    @z1zzz 3 роки тому +1

    Здравствуйте, можете потом снять видео про дизайн паттерны(behavioral, structural), хотя-бы по 2-3 паттерна с каждого.
    Ещё что такое downcasting и почему его использование это плохо.

  • @user-bf5sb1fs1w
    @user-bf5sb1fs1w 2 роки тому +1

    Thank you SO MUCH!!!

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

    Вы очень крут!!!

  • @FoRGeish
    @FoRGeish 3 роки тому +8

    С возможностями современных(ной) IDE писать на каждый чих интерфейс - тоже такое себе занятие, противоречащее KISS'у. Как и с балансом между хард и софт, нужно соблюдать баланс между "все на интерфейсах"/"ни одного интерфейса в проекте". ИМХО

  • @yurim7756
    @yurim7756 3 роки тому +4

    О, холивар )
    Это всё понятно, но есть некоторые вопросы, просто на подумать. Как раз связанные с тем, чем хреново ооп в принципе по сравнению с функциональщиной. Вот в этом видео прямо показывается, как один из недостатков ООП доводится до совершенства.
    1. Так ли часто нужно вставлять новый функционал, который здесь привели в сравнении с тем, что надо всегда солому подстилать и все время делать больше? Например, там вы решили вставить функционал, может раз в полгода, а классов пишете кучу каждый день. И это а) просто заставляет вас делать больше усилий, б) постоянно больше усилий при дебаге или просто при переходах в среде разработки, в попытке выяснить какая реализация используется. А в то же время современные IDE вполне уже не просто текстовые редакторы, и довольно слабый аргумент, что надо лазить потом будет по всему коду, чтобы разорвать при случае зависимость и выставить интерфейс.
    Т.е. это не утверждение, что данный подход плохо, просто сами попытайтесь оценить в своей работе, в своей среде разработки, в каком случае производительность программиста хуже.
    2. Интерфейс уменьшает зависимость, да. Но ее не всегда надо с коробки уменьшать. Программа - это рельсы для поезда. Поезд должен ездить жестко по ним. В первую очередь программа должна быть жесткой, потому как у нее первая задача - работать правильно, выполняя заложенные требования. А уже 2я, или даже 22я, это антагоническая цель - быть гибкой, потому что что-то может измениться в требованиях. Интерфейс - это набор сигнатур методов. А сигнатура - пример сайдэффекта. Т.е. в ООП вообще нет гарантии что передавая один и те же аргументы, вы будете получать одни и те же результаты, потому что дзёбанные объекты имеют состояние (по сути, поля - это глобальные переменные, за которые ругали еще в процедурном подходе). А интерфейс добавляет хардкора в топку, это прям вот идеальный кот в мешке )) Вы еще и имеете возможность подменять реализацию, одна будет у вас в одном случае, другая в другом, и особенно в юнит тестах. Т.е. получается, что вы сознательно в юнит-тестах окружаете код некими конструкциями, которые ТОЧНО будут работать не так, как это работать будет вживую. По сути, что такое сайдэффект. Работа программы зависит, ну типа как от неких глобальных переменных, и черт знает, какие они будут, когда случится бага, и как себя поведет программа в тех или иных случаях. И вы, когда пишете тест, пытаетесь угадать, какие значения переменных в окружении будут в реале, или выставить так, что на ваш взгляд, оно покроет все разные варианты. Много тестов будет просто ради тестов, потому как в реале эти интерфейсы будут только подмножество вариантов своей работы выдавать. А можно и пропустить реальный кейс. (тут я не рассматриваю, что юнит-тесты должны каждую ветку тестить, но смысл, что у вас оверхед будет по тестам).
    Это так, на подумать, это не критика ;) Не всё так однозначно. Хотя, если так случилось, что выбрали ООП, то вариантов как лучше, не так и много )

  • @bandirom
    @bandirom 3 роки тому +12

    Покажите каждый принцип на практике, на джаве или любо чем)

  • @alexanderbelov6892
    @alexanderbelov6892 2 роки тому +13

    10:06 Есть такая штука - рефакторинг кода.
    Делай раз: Создай интерфейсы по принципу SOLID/ISP, которые реализует класс.
    Делай два: Унаследуй жёсткий класс от всех интерфейсов, чтобы он их реализовывал.
    Делай три: Измени клиентов, чтобы они использовали новые интерфейсы вместо жёсткого класса.
    Танцы с бубном окончены.

  • @user-cu3wh4rm7c
    @user-cu3wh4rm7c 3 роки тому +5

    Было бы интересно послушать о TDD. Спасибо за вашу работу

    • @anmaner4822
      @anmaner4822 2 роки тому

      @@a.o.yaroslavov А чем он вреден то? Позволяет сначало задать бизнес-логику в виде тестов, а потом уже писать класс, который будет удовлетворять тесты, тем самым, следовать бизнес-логике

  • @yashkevich8164
    @yashkevich8164 2 роки тому +8

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

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

      На эту тему очень понравилось: ua-cam.com/video/knNaUSLhx-U/v-deo.html )

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

      Ctrl+alt переходит сразу на реализацию

  • @MikhailKolesnikov
    @MikhailKolesnikov 3 роки тому +5

    увы, вызов всего через интерфейсы тоже бывает организован "через одно место".
    например, когда интерфейс делается вида:
    void doJob(JobParameters params, Object yet_another_parameter, Long timeout, String log_prefix, int node_id)
    ну и так далее.... :)

    • @alekseykouzmenko9096
      @alekseykouzmenko9096 3 роки тому +2

      Ну рукожопую жопорукость никогда и никому не победить и не искоренить

  • @FORGIVE123N
    @FORGIVE123N 2 роки тому +2

    Не хватает наглядной демонстрации через блок схемы. Делали на предыдущих принципах, а тут почему-то не стали :(

  • @user-tg1yr1dt4n
    @user-tg1yr1dt4n 2 роки тому +1

    Огромное спасибо за видео но не хватает примера для полного понимания

  • @malferov
    @malferov 2 роки тому +10

    Как рассказывать про инверсию зависимостей и не рассказать про инверсию зависимостей. Тот, кто знает, что такое DI, тот знает, что такое DI. А кто нет - нет. Вместо отлития в граните «все классы должны использоваться через интерфейсы», может быть, имело смысл показать пример, как инвертируются зависимости. На схеме, скажем.

    • @Kan041185
      @Kan041185 2 роки тому

      хах, полез в комменты на середине видео и понял, что примеров не будет ))

  • @artyomzheltyshev8059
    @artyomzheltyshev8059 3 роки тому +4

    3:25 такие задачи как логирование и профайлинг зачастую делаются через аспекты. На первый взгляд это смотрится довольно лаконично, без кучи самодельных интерфейсов и декораторов; вся магия остаётся под капотом АОП-фреймворков. Сергей, сделайте как-нибудь видео про АОП, пожалуйста, мб есть какие-то подводные камни.

    • @alekseykouzmenko9096
      @alekseykouzmenko9096 3 роки тому +1

      Подводные камни провляются в тот момент когда система перестала работать на отлично. Сложно сайд-эффекты отслеживать.

  • @dmytromarchuk3023
    @dmytromarchuk3023 3 роки тому +5

    Зростання вашому каналу! Хорошу справу робите!

    • @MikhailKolesnikov
      @MikhailKolesnikov 3 роки тому +1

      а в чём глубинный смысл писать на вот этом непонятном языке? если ты прослушал этот ролик то ты 100% понимаешь русский язык и можешь на нём выразиться или, хотя бы, сообразить, что твои вирши не всем будут понятны и воспользоваться гугло-транслейтом.

    • @dmytromarchuk3023
      @dmytromarchuk3023 3 роки тому +9

      @@MikhailKolesnikov На якій мові хочу - на такій і пишу. "не всем будут понятны" - я пишу не для всіх, а конкретно автору цього відео, а він українську шарить. Так що фак оф

    • @MaceUA
      @MaceUA 3 роки тому

      @@MikhailKolesnikov Абсолютно понятный язык. Не нравится -- проходи мимо, не задерживайся, сталкер.

    • @meteysh
      @meteysh 3 роки тому

      @@MikhailKolesnikov я, русский, но его писанина мне понятна и даже прикольно, что он так написал :)

  • @core2mind
    @core2mind 3 роки тому +1

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

  • @LyubomirZalizkiy
    @LyubomirZalizkiy 3 роки тому +8

    @Sergey Nemchinskiy Там SRP в назві

  • @starfall7431
    @starfall7431 2 роки тому +14

    11 минут каких-то историй
    хотел понять суть DIP - посмотрел монолог но сути так и не уловил
    было бы неплохо, если бы все это было лаконичнее и без излишних баек

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

      Тут такой рассказчик, он по-другому не умеет

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

    залпом посмотрел

  • @akame6747
    @akame6747 3 роки тому +2

    Хотелось бы про TDD

  • @javavlogger9409
    @javavlogger9409 3 роки тому +1

    Миллион лайков этому видео! Как открыл для себя удобство прогр-я через интерфейсы, до сих пор кипятком ссусь от счастья) Хотелось бы подобный ролик еще и про DI/IoC.

  • @leonkonig5131
    @leonkonig5131 3 роки тому +15

    Добрый день, очень хотелось бы увидеть все принципы SOLID в виде кода, хорошо бы java.

    • @igorilich1379
      @igorilich1379 3 роки тому +9

      В идеале не привязываться в подобных видео к языку. Учимся программировать не на языке, а с использованием языка ) имхо (иначе я бы не смотрел эти ролики)

  • @sergijg
    @sergijg 3 роки тому +6

    К сожалению интерфейсы после релиза системы приходится менять в следствии ее расширения, и иногда весьма интенсивно, и вот тогда начинается просто ад с апдейтом интерфейсов (около сотни). В остальном все достаточно гибко

  • @Alex11Fox
    @Alex11Fox 3 роки тому +9

    Говорит что надо все делать ч/з интерфейс, тогда что же является софткод?

    • @ilya9485
      @ilya9485 3 роки тому +3

      Тоже возник вопрос на этом месте

    • @JackFastGame
      @JackFastGame 3 роки тому +2

      Да, что-то уже попахивает антипаттерном.

    • @aliancechel
      @aliancechel 3 роки тому

      Подожду ответа с вами

    • @truenerdofbotva5831
      @truenerdofbotva5831 3 роки тому

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

  • @antaki93
    @antaki93 2 роки тому +1

    Может быть, я не очень умный, но я посмотрел весь плейлист и по-прежнему не понимаю, почему в описанном случае нельзя просто добавить к классу Server метод authorization() или т.п.? Нужна авторизация - дописываем авторизацию, ну в чём проблема-то?

  • @user-il2bm5us5n
    @user-il2bm5us5n 3 роки тому

    Найкраще пояснення SOLID що я чув, набагато краще ніж Шевчук!

  • @feoktant
    @feoktant 3 роки тому

    Про стабы интересно. После написания такого кода, есть две реализации для поддержки, и один интерфейс.
    Слова "интерфейсы должны быть стабильны"... На практике изменения чаще говорят "никто никому ничего не должен", и меняешь по итогу все имплементации.
    Реализовать такой стаб проще через наследование, чем отдельный интерфейс - изменение будет в двух местах, вместо трёх.

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

      Я тоже не из лагеря «всё через интерфейсы», но аргумент звучит как предложение экономить на семечках.

  • @user-qv4hn6qq4n
    @user-qv4hn6qq4n 3 роки тому +3

    Спасибо, ничего непонятно

  • @gaitavr1992
    @gaitavr1992 3 роки тому +2

    Наверное самый часто нарушаемый принцип)

  • @popuzin
    @popuzin 3 роки тому +1

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

  • @juliusmalkov9620
    @juliusmalkov9620 3 роки тому +4

    во, какраз думал "когда же будет видео про D"))

  • @johnins1646
    @johnins1646 3 роки тому +2

    Приведите, пожалуйста , примеры DIP, было без DIP так, с DIP стало так...

  • @aRRma99
    @aRRma99 3 роки тому +1

    годно

  • @antonkuranov
    @antonkuranov 3 роки тому +2

    Ну вот не факт. Бывают функциональные единицы с несколькими зависимостями, которые используются приватно только в данном контексте и не имеют смысла вне его, но которые все же инъектируются через DI. Писать каждый раз по этому поводу новый интерфейс -- это по большей части моральная мастурбация. Тут больше применимы принципы yagni и kiss.

  • @nik_fine
    @nik_fine 2 роки тому

    А разве интерфейс или декоратор не нарушают принцип единственной ответственности?

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

    не знаю оговрка это была или нет но -SRP принцип единственной ответственности.
    Каждый класс должен иметь только одну зону ответственности.

  • @vitalyvolovodenko3473
    @vitalyvolovodenko3473 3 роки тому

    Даеш видео о паттернах

  • @Eladanius
    @Eladanius 3 роки тому +1

    Ничерта не понимаю, как добавления новых методов в класс сервера аффектит мой класс клиента. Допустим у меня есть объект класса Сервер в классе Клиент. Через него я вызываю необходимые мне методы. Как добавление новых методов в класс Сервер может сломать работу класса Клиент??? Ну добавились новые методы и что? Хочу вызову, хочу нет... Объясните плиз, я вообще не отдупляю плюсы работы с классами через интерфейс!

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  3 роки тому +1

      Новый метод может, например, принимать новый тип данных. А этот тип данных может быть недоступен для клиентского кода - например пекеджи не обновились. Вот и аффект

  • @user-gw6df6ns7e
    @user-gw6df6ns7e 3 роки тому +3

    Ну не особо надо все вызывать через интерфейс. Если надо выделить интерфейс можно за 5 секунд. Зачем его делать заранее? Хотя вот если у нас библиотека, то ее Api лучше через интерфейсы развязать.

  • @artursveshnikov7668
    @artursveshnikov7668 3 роки тому +2

    Сергей, плиз, го антипаттерны.

  • @fel1ow
    @fel1ow 2 роки тому

    На 04:55 он говорит "добавить шаблон прокси из гов". Что за гов? Благодарю за ответ.

  • @user-ez2yf3yd3z
    @user-ez2yf3yd3z 2 роки тому

    OK!

  • @wayfarer2178
    @wayfarer2178 3 роки тому +4

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

    • @maxlich9139
      @maxlich9139 3 роки тому

      да ваще странно, обычно руководство в код не лезет. только тимлиды, сениоры и архитекторы

    • @wayfarer2178
      @wayfarer2178 3 роки тому

      @@maxlich9139 обычно в любой компании есть коммуникация. и обычно трекание времени и отслеживание этого действа - это задача больше PM, чем тимлида или архитектора. и обычно руководство прекрасно в курсе, как ускорить или замедлить проект.

    • @maxlich9139
      @maxlich9139 3 роки тому

      @@wayfarer2178 ну тонкостей программирования они не обязаны знать

  • @user-hj6oh4bw3n
    @user-hj6oh4bw3n 2 роки тому +1

    Ребят, возник вопрос, который прям не дает покоя:
    - Не противоречит ли принципе DIP паттерну Creator. По DIP надо объекты передавать другим объектам через их интерфейсы, а по Creator'у эти объекты следует создавать там, где они используются. Как разрешить это противоречие?

    • @ergo_____3491
      @ergo_____3491 2 роки тому

      Разрешается противоречие устранением ошибок в понимании принципов)
      По DIP надо создавать объекты типа интерфейса, который реализует класс объекта, а не передавать что-то.
      Например, есть класс "МумбаЮмба", который имплементирует интерфейс "МумбаЮмбаИнтерфейс".
      Теперь в другом классе тебе понадобился объект класса МумбаЮмба.
      Ты можешь создать его так:
      МумбаЮмба мумбаЮмба = new МумбаЮмба();
      А DIP у тебя просит всего навсего тип переменной указать интерфейсный:
      МумбаЮмбаИнтерфейс мумбаЮмба = new МумбаЮмба();
      Тогда потом в эту переменную ты сможешь отправить объект любого класса, имплементирующего интерфейс МумбаЮмбаИнтерфейс.

    • @user-hj6oh4bw3n
      @user-hj6oh4bw3n 2 роки тому +1

      @@ergo_____3491 Разве этого достаточно? У меня, конечно, много ошибок в понимании, но я думал так:
      Один из примером реализации DIP является dependency injection (здесь уже не inversion). Благодаря этому принципу и надо передавать одни классы в другие через интерфейсы, а не создавать одни внутри других

  • @user-si4qz6ps9o
    @user-si4qz6ps9o 2 роки тому +1

    Я только не понял почему в видео про принцип открытости закрытости та же самая инф

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

      Потому что автор сам не разобрался

  • @user-ry3ci8qh9k
    @user-ry3ci8qh9k 3 роки тому

    Компьютерная инженерия-это IT ? Если пойти в университет на такой факультет,можно ли потом пойти работать программистом ?

    • @MaceUA
      @MaceUA 3 роки тому

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

    • @user-di8ee7tg9u
      @user-di8ee7tg9u 3 роки тому +1

      Программная инженерия, так часто называют. Как и написали выше, больше создадут среду, дадут пищу для размышления, какие-то основы основ. А хочешь программировать - всё сам. Хотя в ВШЭ, как понимаю, все условия, чтобы разработка занимала все курсы обучения.

  • @user-mi6vg2nw2f
    @user-mi6vg2nw2f 3 роки тому +10

    GRASP

  • @adskfksefn
    @adskfksefn 3 роки тому +3

    а примеров бы

  • @user-di9vl7ll7z
    @user-di9vl7ll7z 3 роки тому +1

    8:05
    Берете и расширяете функциональность в нужном....шта?

  • @romawar1869
    @romawar1869 2 роки тому

    что такое юнит тест ?

  • @maxlich9139
    @maxlich9139 3 роки тому +4

    Единственный минус DI - все превращается в магию, и потом хрен разберешься что откуда берется, и что как с чем связано

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

    что значит вызывать класс через интерфейс?)

  • @Vectoreal
    @Vectoreal 3 роки тому +1

    Где же инверсия? Что инвертируют-то? И при чём тут интерфейсы? :)

  • @lyloo6577
    @lyloo6577 3 роки тому +5

    Не на каждый класс интерфейс, а на каждый класс, содержащий сложное поведение - интерфейс. Ну не делать же интерфейсы для dto и подобных

    • @LinDahai88
      @LinDahai88 3 роки тому +2

      А почему нет? Допустим dto который надо записать в базу или сериализовать куда-то или один большой dto конвертировать в несколько маленьких.. И что всю эту функциональность пихать в одну реализацию? А если завтра потребуется поменять серализацию из json в bin, или xml? ИМХО делаем dto с чистыми данными и дальше декоратором наворачиваем всю эту логику.. Проблема в том что как правило программисты сначала пишут реализацию а потом из нее extract interface. Но на практике чаще всего класс реализует несколько интерфейсов, а вся та реализация которая была написана ранее является частным случаем и если из нее выделять интерфейс то он должен быть не один а несколько. Это вечная проблема: вместо того чтобы идти от общего - подумать, абстрагироваться, декомпозировать абстракции, и потом уже приступать к частному - т.е. к реализации конкретных классов, люди сначала хардкодят чтобы работало а потом думают. Поэтому все и пользуются мощными IDE которые по сути ускоряют скорость написания кода а не улучшают качество мысли. Если бы приходилось кодить в блокноте то тут же хочешь не хочешь а быстрее сначала подумать а потом только писать.

    • @lyloo6577
      @lyloo6577 3 роки тому

      @@LinDahai88 >И что всю эту функциональность пихать в одну реализацию?
      Композицию никто не отменял
      > если завтра потребуется поменять серализацию из json в bin, или xml?
      Нужны отдельные интерфейсы для json сериализации, отдельный для xml и т. д.
      > ИМХО делаем dto с чистыми данными и дальше декоратором наворачиваем всю эту логику..
      Почему бы нет, не вижу противоречий. Для ясности, общий интерфейс(ы) над всеми дто или логической группой дто - нормально и правильно. По интерфейсу для каждого класса дто - как-то не очень.

    • @LinDahai88
      @LinDahai88 3 роки тому +2

      @@lyloo6577
      > Нужны отдельные интерфейсы для json сериализации, отдельный для xml и т. д.
      Не нужны. Иначе это будут интерфейсы отталкивающиеся от реализации а не от клиентского кода. И начнется: если это json то делаем одно иначе если это xml делаем другое иначе если это bin - третье.... Поставьте себя на место разработчика который будет пользоваться Вашим классом: ему нафиг не нужно знать каким способом вы это делаете. Он знает только о массиве байт и о типе из которого этот массив был получен и два метода Serialize/Deserialize. Остальное для него - магия, избавьте его от этого головняка - у него другая задача. Зато если ходите то хоть шифрование прикрутите к своей сериализации - клиент вообще ничего не почувствует. В этом то и смысл интерфейсов сделать так чтобы клиентский код вообще никак не поменялся при изменениях в реализации класса.
      > Для ясности, общий интерфейс(ы) над всеми дто или логической группой дто - нормально и правильно.
      Общий интерфейс над группой дто? Т.е. при изменении или добавлении дто-шек будет меняться интерфейс? Или я не так понял или нафига оно надо? Это мы тогда возвращаемся к теме interface segregation.
      > По интерфейсу для каждого класса дто - как-то не очень
      Опять таки здесь нет и не должно быть соответствия между дто и интерфейсом. Например класс Pet не реализует интерфейс IPet. Таких интерфейсов быть не должно. Должно быть класс Питомец реализует интерфейсы Гладебильный, Кормибельный и Играбельный. Чувствуете разницу? Один класс но с разными интерфейсами для разных клиентов. Например хозяин может покормить питомца но гости могу только играть и гладить. Так же и с дто-шками - класс один но интерфейсы разные могут быть для разных задач.

    • @lyloo6577
      @lyloo6577 3 роки тому +1

      ​@@LinDahai88 вы сами приводите примеры "Кормибельный", "Играбельный" - видно что ваши классы реализуют сложное поведение, то есть уже не dto.
      > Например класс Pet не реализует интерфейс IPet. Таких интерфейсов быть не должно.
      Я примерно об этом же пишу. Но мне сложно придумать пример из реальной жизни когда все поля дто можно подвести под интерфейсы в стиле "Кормибельный", "Играбельный" Если не обращаться к ДТО объекту напрямую то это именно и получится IPet
      Вы давно в программировании? )

    • @LinDahai88
      @LinDahai88 3 роки тому

      @@lyloo6577
      > Вы давно в программировании? )
      6 лет, C#, Unity3D
      > Но мне сложно придумать пример из реальной жизни когда все поля дто можно подвести под интерфейсы в стиле "Кормибельный", "Играбельный"
      Действительно трудно, но та же сериализация.., или например форматирование.... Сами поля дто-шки трудно назвать полноценными методами т.к. это скорее всего геттеры.., так что думаю это можно не считать. ;)
      Вообще мы тут спорим про dto. Но если задуматься то это уже не ООП, потому что если это чистые данные без логики которая их обрабатывает то где тогда high cohesion?

  • @majeunesse4722
    @majeunesse4722 3 роки тому +1

    Теперь у меня есть принципы, знаете-ли, и я себя не на помойке нашел

  • @user-ld8eu7qz4g
    @user-ld8eu7qz4g 3 роки тому +5

    Не ну прям на каждый класс - это хрень. На важные классы - да, надо.

    • @user-ss2rj4wz5s
      @user-ss2rj4wz5s 3 роки тому

      Как определить, насколько класс важен?
      И как определить эту грань, когда он уже недостаточно важен, для описания его интерфейса?

    • @user-ld8eu7qz4g
      @user-ld8eu7qz4g 3 роки тому

      ​@@user-ss2rj4wz5s это предохраняет от тех случаев, когда класс используют в рандомных местах проекта, а потом его понадобилось изменить. Некоторые классы (почти) никогда не изменяются и используются в 1 месте. Если 3 мест и больше - точно надо, если проходит ось изменений - точно надо. Если есть бешеные джуно-индусы - точно надо. А ещё это касается только больших проектов, всяким сайтописателям хватает интерфейсов у фасадов модулей.

    • @user-gw6df6ns7e
      @user-gw6df6ns7e 3 роки тому

      Добавляйте интерфейс если почувствовали, что он нужен. IDE это умеет делать. Если делаете библиотеку, то все что торчит из нее наружу должно иметь интерфейс. В коде сервиса такой необходимости нет. Это ваш код и не надо городить абстракции раньше времени.

  • @user-qr1dv4sx7n
    @user-qr1dv4sx7n 3 роки тому

    Можно пожалуйста книги для новичков про java на русском.

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  3 роки тому +1

      видео про книги для программиста: ua-cam.com/video/jOW7_Ie4g-w/v-deo.html

    • @user-qr1dv4sx7n
      @user-qr1dv4sx7n 3 роки тому

      @@SergeyNemchinskiy благодарю.

  • @denispriyomov6086
    @denispriyomov6086 3 роки тому

    Ага, когда пишешь на Яве, когда производительность - это ниже твоего достоинства, когда это не говно-код, а ты так видишь... тогда таки да - всё виртуальное и везде интерфейсы.
    Осталось только, чтоб авторы STL одумались и всё переписали на интерфейсах.

  • @igorilich1379
    @igorilich1379 3 роки тому +1

    Что там по мок и стаб
    Кратенько )

  • @bahdanshyshkin7918
    @bahdanshyshkin7918 3 роки тому +1

    Название поправьте!

  • @stan5214
    @stan5214 3 роки тому

    Декомпозиция предметной области

    • @annaumrykhina2540
      @annaumrykhina2540 3 роки тому +1

      плейлист про декомпозицию: ua-cam.com/play/PLmqFxxywkatSezlaoxwFbdBBnAk_JJ__5.html

  • @makskors5002
    @makskors5002 2 роки тому

    DRY тоже надо :)

  • @SlavaCh
    @SlavaCh 3 роки тому +2

    Крч все видео в одном предложение: юзайте классы через интерфейсы.

    • @user-eu5ee8vk7p
      @user-eu5ee8vk7p 3 роки тому +3

      на самом деле тут еще надо понимать, зачем ты это делаешь, это объясняется в видео :) если просто услышать эту фразу и начать применять то можно еще большего говна поесть. Так и под дтошки интерфейсы можна начать пилить

    • @maxlich9139
      @maxlich9139 3 роки тому +1

      @@user-eu5ee8vk7p интерфейсы под дто-шки!? это жестко))) хотя иногда встречается в том или ином виде

  • @alexkhutornyi403
    @alexkhutornyi403 3 роки тому

    GoF patterns, растолкуй, плиз

    • @maxlich9139
      @maxlich9139 3 роки тому

      был же целый плейлист

  • @arthurkhasanov8964
    @arthurkhasanov8964 3 роки тому +2

    Что значит замокать ?)))

    • @alekseykouzmenko9096
      @alekseykouzmenko9096 3 роки тому +2

      Использовать фейковый объект вместо реального. Позволяет изолировать часть логики и/или подменить реализацию метода на более простую.

    • @maxlich9139
      @maxlich9139 3 роки тому

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

  • @vitall789
    @vitall789 3 роки тому

    Базовые определения не для понимания, а для галочки такое ощущение!

  • @Buarpa
    @Buarpa 3 роки тому +1

    испорчу картину лайков, поставлю 334-ый :D

  • @vufer3d
    @vufer3d 3 роки тому

    DRY KISS

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

    И ЭТО ПО ПРЕЖНЕМУ СЕРГЕЙ НЕМЧИНСКИЙ, ИУУУУУУУУУ 😊

  • @diandjelo
    @diandjelo 3 роки тому

    в названии - DIP, в превью - SRP

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  3 роки тому

      Это дизайнер опять ошиблась 😉

  • @alexkhutornyi403
    @alexkhutornyi403 3 роки тому

    Mock vs stub

  • @Jdivanchik
    @Jdivanchik 2 роки тому

    Как показала практика, "все классы через интерфейсы" это тоже бред. Нет смысла загонять все классы в интерфейсы! К примеру не стоит делать интерфейсы для моделей или скажет для тех же DTO. А тот кто это сделает или будет призывать к этому на мой взгляд так же является нехорошим программистом.
    В интерфейсы стоит загонять сервисы, провайдеры, репозитории, обработчики.... То есть те классы, которые что-то делают с окружением, а все те классы, которые ничего не делают с окружением в интерфейсы нужно загонять крайне взвешенно, что бы не наплодил слишком много ненужных интерфейсов.

  • @user-tm3uz6ij8t
    @user-tm3uz6ij8t 4 місяці тому

    Вот здесь крутое объяснение этого принципа:
    ua-cam.com/video/Uq10IqZhf7U/v-deo.htmlsi=yITNxUdvpP1f4fhb

  • @user-is4ji8mr7j
    @user-is4ji8mr7j 3 роки тому +1

    +++++