SOLID: Принцип подстановки Барбары Лисков/ LSP (The Liskov Substitution Principle)

แชร์
ฝัง
  • เผยแพร่เมื่อ 29 ม.ค. 2025

ความคิดเห็น • 444

  • @SergeyNemchinskiy
    @SergeyNemchinskiy  3 หลายเดือนก่อน

    💪Новый поток advanced тренинга Enterprise patterns стартует 2.12 - go.foxminded.ua/4eXh83k

  • @-ebaka
    @-ebaka 4 ปีที่แล้ว +236

    Роберт что-то непонятное сказал, то ли дело Барбара

    • @6598335
      @6598335 4 ปีที่แล้ว

      XDXDXD

    • @СергО-л6ф
      @СергО-л6ф 3 ปีที่แล้ว +3

      Математически чёткое описание всегда более точное, чем словесное описание. Например,
      Правила Ассоциативноти и Дистрибутивности и звучат лучше...

  • @vadimsokhatsky2748
    @vadimsokhatsky2748 2 ปีที่แล้ว +7

    Сергей, спасибо! С вашими видео обучение программированию становится сплошным кайфом!

  • @alokym86
    @alokym86 2 ปีที่แล้ว

    Я знаю чому для Вас формулювання Барбари Лісков складне і заплутане! Все тому, що для Вас і квадрат - це не прямокутник!)
    Дякую за відео. Приклад з квадратом підірвав мій мозок.

  • @stakhovskiy
    @stakhovskiy 4 ปีที่แล้ว +40

    Август месяц на дворе, а его все еще зовут Сергей Немчинский. Хосспаде!
    Спасибо за видео 😄Лайк.

    • @z1zzz
      @z1zzz 4 ปีที่แล้ว

      А в чём прикол?

    • @igorost795
      @igorost795 3 ปีที่แล้ว

      Попрошу! Сергей "тутромбик" Немчинский!

  • @whoiam6395
    @whoiam6395 3 ปีที่แล้ว +1

    Спасибо огромное!!! В 3х словах рассказал то что я не смог понять ни в одном видео до этого.

    • @whoiam6395
      @whoiam6395 3 ปีที่แล้ว

      А я их пересмотрел штук 10

    • @Virus-td9nc
      @Virus-td9nc 2 หลายเดือนก่อน

      а я снова нихуя не понял

  • @РостикНазаренко-п8с
    @РостикНазаренко-п8с 2 ปีที่แล้ว

    Дуже вам дякую за пояснення. Все просто і зрозуміло )

  • @Snake19S
    @Snake19S 4 ปีที่แล้ว +2

    Сергей, вы такой живчик в этом видео. Отлично получилось!

  • @masterbedroom594
    @masterbedroom594 4 ปีที่แล้ว +1

    Сергей, выражаю вам искреннюю благодарность

  • @protchenko.oleksandr
    @protchenko.oleksandr 2 ปีที่แล้ว

    Або це просто вже 100те відео про Лісков і я нарешті зрозумів, або це найкраще з тих відео що я бачив і я зрозумів =))

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  2 ปีที่แล้ว

      я просто умею объяснять :)

  • @BukasovMaxim
    @BukasovMaxim 4 ปีที่แล้ว +43

    Я бы еще добавил, что при оверрайде неабстрактных методов, новый метод должен уметь принимать параметры в таком же диапазоне или шире (но ни в коем случае не уже), а при возвращении значений - в таком же диапазоне или уже (но ни в коем случае не шире).
    Например в каком-то классе есть метод, который умеет принимать число от 1 до 100 и возвращать от 1 до 10. Если его заоверрайдить так, что новый будет уметь принимать 0..200, а возвращать 3..5 - существующий клиентский код будет доволен. А вот если переписать так, что новый метод умеет принимать только 1..50 или вдруг возвращает 0..20 - то существующий клиентский код может быть неприятно удивлён.
    Также можно было бы еще сказать, что список выбрасываемых исключений можно сокращать, а исключения - конкретизировать, а вот наоборот - добавлять новые или расширять существующие - нельзя. Но с контролируемыми исключениями компилятор Джавы в этом плане сам подскажет, что можно, а что нет, а неконтролируемые... на то они и неконтролируемые :)

    • @vladzaiko5012
      @vladzaiko5012 3 ปีที่แล้ว

      что то я не уверен что вы правильно написалали, если базовый класс возвращал от 1 до 10, а наследник будет возвращать от 3 до 5 а это ведь нарушение принципов о которых говорит Сергей - наследник не может возвращать меньше чем базовый класс. Базовый класс будет ожидать что при определенных параметрах вернется 10, а наследник вернет максимум 5 и все сломается.

    • @BukasovMaxim
      @BukasovMaxim 3 ปีที่แล้ว +3

      @@vladzaiko5012 Представьте, что есть клиентский код, который умеет разговаривать на английском, французском и немецком. Есть базовый компонент, который иногда выдаёт клиенту что-то на английском, а иногда - на немецком. Клиент понимает эти сообщения от компонента.
      Если заменим этот компонент на новый, который будет выдавать сообщения только на английском (т.е. сузим диапазон возвращаемых значений), то клиентский код всё еще будет понимать эти сообщения. А вот если новый компонент вдруг заговорит на японском (т.е. расширим диапазон возвращаемых значений), то клиентский код сломается - потому что клиентский код не знает, что делать с сообщениями на японском.

    • @vladzaiko5012
      @vladzaiko5012 3 ปีที่แล้ว

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

    • @BukasovMaxim
      @BukasovMaxim 3 ปีที่แล้ว +5

      @@vladzaiko5012 Речь не о новых методах. Речь о старых методах, которые в новых компонентах вдруг начали выдавать на выход то, что старые компоненты не выдавали.
      Пример: батарейка (как компонент). Допустим у нас есть электрическая схема (клиент), которой нужно питание +5В +/-10% (т.е. от 4.5 до 5.5 - будет работать). Если у нас есть батарейка, которая выдаёт +5В +/- 5% (т.е. от 4.75 до 5.25), то все ОК, схема будет работать и не сгорит (потому что при замене компонентов выходные диапазоны можно сужать без проблем). Но если мы вставим батарейку +5В +/-20%, то она может дать или слишком мало (и схема не заработает) или слишком много (и схема сгорит). Поэтому, при подмене компонентов, расширять возвращаемый диапазон - нельзя (можно только сужать).
      Входной диапазон - наоборот: сужать нельзя (чтобы клиент не послал в компонент что-то такое, что он не поймёт), а расширять - можно (чтобы компонент был не глупее, чем его предок).

    • @catmother8368
      @catmother8368 3 ปีที่แล้ว +1

      @@BukasovMaxim спасибо за отличное объяснение!
      А что, если у нас есть класс User и класс Admin, который является наследником от User? Допустим, в User есть метод, вохвращающий все права пользователей. User будет возвращать стандартные разрешения типа редактировать аккаунт и проч. Но у Admin нужно будет расширять этот список. Верно ли я понимаю, что в данном случае произойдёт нарушение принципа LSP?
      Как этого избежать? Не лучше ли выделить отдельный класс с правами, чтобы не нарушать SRP?

  • @НиколайЮрченко-о2й
    @НиколайЮрченко-о2й 4 ปีที่แล้ว +7

    Классное видео, спасибо за детальное и простое объяснение, хотелось бы еще послушать про паттерн pipeline.

  • @АлексейПоляков-ш1э
    @АлексейПоляков-ш1э 4 ปีที่แล้ว +7

    TDD - ДА! Про return null - ДА!
    Спасибо за видео!

  • @bumer7721
    @bumer7721 4 ปีที่แล้ว +14

    Об ACID интересно послушать.
    А за SOLID благодарю)

    • @maxlich9139
      @maxlich9139 4 ปีที่แล้ว

      было, Владимир Кузнецов рассказывал.

    • @bumer7721
      @bumer7721 4 ปีที่แล้ว

      @@maxlich9139 Дякую! Шукатиму.

  • @romansharpe1131
    @romansharpe1131 4 ปีที่แล้ว +5

    Есть 2 класса Pistol и Rifle. Оба должны стрелять и перезаряжаться, значит выносим эту логику в класс Weapon и наследуемся от него. Появлятся новое оружие Knife, которое тоже атакует (стреляет) и также наследуется от Weapon. Теперь нож и стреляет, и перезаряжается. Реализуем LSP: между классами Weapon -> Pistol/Rifle делаем прослойку Gun и выносим туда логику перезарядки, а в Weapon оставляем только атаку/стрельбу. В итоге получаем: Weapon -> Gun -> Pistol/Rifle и Weapon -> Knife

    • @JackFastGame
      @JackFastGame 4 ปีที่แล้ว

      Что делать, если к такому пришли только после написания кода? Например, нужно было сделать пистолет и ружьё, написали классы: Weapon -> Pistol, Weapon -> Rifle, а потом заказчик добавил в ТЗ нож. Что теперь делать?

    • @romansharpe1131
      @romansharpe1131 4 ปีที่แล้ว

      ​@@JackFastGame по нормальному неплохо было бы продумать все это заранее. Здесь же я привел свой пример, как выглядит LSP на практике.

    • @0imax
      @0imax 4 ปีที่แล้ว

      @@JackFastGame Если код был написан правильно, то другие классы обращались к оружию через интерфейс Weapon и знать не знали, что там внутри. Тогда, если расширить структуру наследования от Weapon, как в комментарии выше, для внешнего кода работа этого класса не изменится.

  • @YuretsUA
    @YuretsUA 4 ปีที่แล้ว

    Очень доступное объяснение, особенно в разрезе примеров. Сразу вспомнил где я уже наговнокодил...

  • @kotanhp3115
    @kotanhp3115 2 ปีที่แล้ว

    Хорошее видео, жду такое же про Оксимирона

  • @TheHosuwisp
    @TheHosuwisp 4 ปีที่แล้ว +138

    Математический вариант Барбары все разложил по полочкам, а то так много воды и ничего не понятно.

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  4 ปีที่แล้ว +10

      ахаха. Ну, рад за вас :)

    • @ffconsole3467
      @ffconsole3467 4 ปีที่แล้ว +46

      Попався, математiк

    • @fakerliar6599
      @fakerliar6599 4 ปีที่แล้ว +13

      Тоже объяснение Барбары показалось более простым и понятным, хотя не математик. Может это потому что я женщина?:D

    • @murationametisation4347
      @murationametisation4347 3 ปีที่แล้ว +2

      Чувак, и мне показалось вариант Барбары намного ясный и простой. Но задело то, что автор видео так обобщает, "всем непонятно". Бро, как раз таки и понятно. Это может для гуманитариев проблема понять из-за боязни математики.

    • @lindx2533
      @lindx2533 3 ปีที่แล้ว +8

      странно что ты за этим вариантом полез на ютьюб к немчинскому

  • @samuro2ua
    @samuro2ua 4 ปีที่แล้ว +3

    Сергей, тема разработки через тестирование очень интересна! Как и SOLID. Спасибо.

  • @sergekim
    @sergekim 4 ปีที่แล้ว +2

    Спасибо большое, Сергей!)

  • @LeoMrakobes
    @LeoMrakobes 4 ปีที่แล้ว +34

    @Sergey Nemchinskiy уже раньше обещал про "почему нельзя возвращать null"

  • @andrey7829
    @andrey7829 11 หลายเดือนก่อน

    Очень понятно объясняете - супер, спасибо

  • @sick_bear
    @sick_bear 2 ปีที่แล้ว

    Наконец-то я понял этот принцип)

  • @БендерЗадунайский-щ9ы
    @БендерЗадунайский-щ9ы 4 ปีที่แล้ว +127

    надо!
    про тест фёст надо
    про нуль из методов
    и ДОСКУ МАРКЕРНУЮ! НАДО!

    • @Asmaers
      @Asmaers 4 ปีที่แล้ว

      и про красную футболку!

    • @VitaliyZlobin
      @VitaliyZlobin 4 ปีที่แล้ว +2

      доску особенно, уши режет

    • @kspshnik
      @kspshnik 3 ปีที่แล้ว

      дададад! и про TDD и про null надонадонадо!

    • @КазимБерловский
      @КазимБерловский 3 ปีที่แล้ว

      Доска как раз под бумагой. Приглядись)

  • @Madeniath
    @Madeniath 4 ปีที่แล้ว +56

    Про TDD интересно было бы посмотреть.

  • @yuriyfedoryshyn5206
    @yuriyfedoryshyn5206 4 ปีที่แล้ว +4

    looking forward to a TDD video))

  • @ВадимКорженко-э8б
    @ВадимКорженко-э8б 4 ปีที่แล้ว +1

    TDD интересно. С удовольствием послушаю.

  • @vladyarets3596
    @vladyarets3596 3 ปีที่แล้ว

    1:16 ну нафиг)) Как это прочитать получилось?!)
    1:50 а не. вот тут нафиг, дяде Бобу спасибо огромнейшее!

  • @ntvisigoth
    @ntvisigoth 4 ปีที่แล้ว +2

    @Sergey Nemchinskiy: Мужик, здоровья тебе! Отличное пояснение! ;)

  • @wandos777
    @wandos777 2 ปีที่แล้ว

    Супер, Сергей) Спасибо большое за видео, однозначно лайк!)

  • @nataliia9346
    @nataliia9346 4 ปีที่แล้ว +1

    Хотелось бы с таким классным объяснением и примерами послушать о Паттернах Программирования :)

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  4 ปีที่แล้ว

      эм.... Ну вот же оно: foxminded.com.ua/grasp-gof-design-patterns-advanced-on-line-course/

  • @NikolayMishin
    @NikolayMishin 3 ปีที่แล้ว +2

    Самый сложный принцип, я вечно сыплюсь на нем))) но объяснение с прямоугольником и квадратом просто огонь! Спасибо 🙏

    • @yuriytheone
      @yuriytheone ปีที่แล้ว +1

      Ты сыпишься, потому что Solid ложны. Каждый принцип ложен! Давай про Srp. Когда ты создаёшь дочерний класс, ты его создаёшь именно таким, какой нужен именно в твоём коде. И именно с таким интерфейсом, который нужен твоему софту. Далее Ocp - ты не только можешь менять код метода, но и должен если это нужно для оптимизации. Да, представь себе Ocp тоже ложен. Далее Lsp - зачем тебе порождать наследников и закидывать в какой либо метод работающий с классом родителем. Ну, вот ты и не можешь объяснить... У немчи6ского яйц нет признать, Solid - фуфло.

  • @ПашаХЗ-м8й
    @ПашаХЗ-м8й 4 ปีที่แล้ว +1

    Давно ждал!

  • @chat_mayevskogo
    @chat_mayevskogo 3 ปีที่แล้ว

    Я себе тоже такую футболочку взял, тока черную, чтоб прям в тему последних времен было)
    Это когда джаву в js тоже будут компилить, наверное)

  • @СергейКарпиченко-с6б
    @СергейКарпиченко-с6б 4 ปีที่แล้ว +1

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

  • @alexeydeyev4970
    @alexeydeyev4970 4 ปีที่แล้ว +1

    Очень интересно про Test First!!! В топ!!

  • @demidovmaxim1008
    @demidovmaxim1008 4 ปีที่แล้ว

    Большое спасибо за выпуск!!!

  • @dmitriykozyrev8835
    @dmitriykozyrev8835 4 ปีที่แล้ว +1

    Сразу лайк, спасибо тебе большое!

  • @woodzimierz9621
    @woodzimierz9621 4 ปีที่แล้ว +2

    Про TDD очень интересно.

  • @vanilla1006
    @vanilla1006 4 ปีที่แล้ว +2

    TDD, буду рад выслушать

  • @AnnaIsHere
    @AnnaIsHere 4 ปีที่แล้ว +45

    Хотелось бы больший упор на "как надо" вместо "как не надо"

    • @Gusto20000
      @Gusto20000 3 ปีที่แล้ว +6

      Просто берете как не надо и делаете не так и будет как надо

    • @fractalzombie
      @fractalzombie 3 ปีที่แล้ว

      С опытом придёт.

    • @АнтонДудкевич
      @АнтонДудкевич 3 ปีที่แล้ว

      @@Gusto20000 и если это приходится объяснять, то, наверное, лучше никак не надо ;)

    • @screamer8932
      @screamer8932 2 ปีที่แล้ว

      @@Gusto20000 Часто бывает 101 способ как не надо и только парочку как надо.
      Кск би так убегая от плохого 98 способа не попасть в 86))

    • @НиколайКоваленко-г2к
      @НиколайКоваленко-г2к 8 หลายเดือนก่อน

      что касаемо lsp то что бы его не нарушать нужно просто придерживаться ооп. Надо постараться что бы его нарушить.

  • @Zlobusz
    @Zlobusz 4 ปีที่แล้ว +1

    Программирую на php в Symfony. На самом деле крайне редко приходится использовать наследование. Чаще фреймворк предоставляют интерфейсы, чем абстрактные классы. А наследоваться от какой-то конкретной реализации - тоже не совсем приятно. Поэтому случаев наследования можно по пальцам одной руки пересчить. Но принцип постановки Лисковой зашёл. Спасибо! Теперь бы про инверсию зависимости послушать)

    • @alexeyb5830
      @alexeyb5830 2 ปีที่แล้ว

      потому, что ооп это не про наследование. В чистой архитектуре про это написано. Ооп это про полиморфизм. Старину Боба видимо не всего Немчинский читал, либо читал и не понял.

  • @user-hv8rh8nk9d
    @user-hv8rh8nk9d 4 ปีที่แล้ว

    Отлично. Про тесты видео нужно

  • @Дмитрий-х2й5р
    @Дмитрий-х2й5р 4 ปีที่แล้ว +6

    Спасибо.
    Только с квадратом как быть? Разве при наследовании у него не разумно переопределить метод подсчета площади?

    • @danilakapitanov7044
      @danilakapitanov7044 3 ปีที่แล้ว +2

      Проблема не столько с определением площади, сколько с установкой сторон в клиентском коде. Правильным решением является создание абстрактного класса Figure с методом вычисления площади, от которого наследуется отдельно Rect и отдельно Square и реализуют метод вычисления площади. При этом для клиентского кода логика работы по установке сторон Rect и Square становится разная. Т.е. прямоугольник и квадрат по сути это разные сущности, как ,например, прямоугольник и круг.

    • @alexanderbelov6892
      @alexanderbelov6892 3 ปีที่แล้ว +2

      @@danilakapitanov7044 Раз уж речь про клиентский код работы с фигурами, то характеристики фигур должны прописываться при создании, и отсутствовать методы их изменения, которые будут разными для разных фигур. К примеру для фигур могут быть методы get_square() для площади, и scale() для изменения размера. Но никак не изменения характеристик описывающих фигуру по отдельности. Для изменения фигуры с другими сторонами нужно создать новую фигуру, а предыдущую удалить.

  • @СанжарСовет-ъ5ц
    @СанжарСовет-ъ5ц 3 ปีที่แล้ว

    ну круто я понял как делать не надо ,а как делать надо сам разберусь спасибо лайк щищ

  • @xdef42
    @xdef42 4 ปีที่แล้ว +35

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

    • @nanvlad
      @nanvlad 4 ปีที่แล้ว +4

      Ты сраный рукожоп по версии Немчинского)) Я тоже агрегирую и композирую с интерфейсами + ещё дженерики

    • @alexeydeyev4970
      @alexeydeyev4970 4 ปีที่แล้ว +4

      Имплементирование можно с натяжкой отнести к наследованию.

    • @grommaks
      @grommaks 4 ปีที่แล้ว +1

      аналогично

    • @makaroningable
      @makaroningable 4 ปีที่แล้ว

      Я наследую только абстрактные классы где имплементирую основное поведение, частично переопределяемое в классах наследниках. Но вот так чтоб в чистом виде унаследоваться от другого конкретного класса - такого тоже нет.

    • @woodzimierz9621
      @woodzimierz9621 4 ปีที่แล้ว

      @@makaroningable есть товарищи, которые отрицают любую форму наследования

  • @UnrealSPh
    @UnrealSPh 4 ปีที่แล้ว +7

    Возможно, описание самой Барбары станет более понятным, если понимать когда она его предложила и как выглядели ассоциации типов в ЯП в то время, так как *спойлер* наследование не единственный способ ассоциации классов, а скорее частный случай.
    Насчёт использования наследования вы скорее всего заблуждаетесь, но причина заблуждения это легаси информация, которую из года в год перевыпускают в требованиях к коду.
    Если вы боретесь с копипастингом кода в проекте, то для этого больше подходит композиция кода.
    А если и методология разработки у вас не waterfall, то n-ступенчатая иерархия наследования превратит процесс изменения кода в ад (не забываем, что классы содержат ещё и стейты).
    Наследование сильный инструмент, но его главное назначение в продуктах, которые должны иметь жёсткую структуру иерархии, а так же максимально долгое время жизни самой иерархии. Напрмер фреймворки. Там наследование чувствует себя хорошо.

  • @РинатРаот
    @РинатРаот 4 ปีที่แล้ว

    Ах**нно)
    наконец то понял в чём фишка этого принципа

  • @kyryloshamraiev6289
    @kyryloshamraiev6289 3 ปีที่แล้ว +2

    Очень наглядное объяснение. Проще говоря, нужно наследовать большее от меньшего, а не наоборот. Все станет на свои места, если считать, что квадрат - это частный случай прямоугольника, а не его наследник. Именно такой подход применят учёные. Потому обьяснение Барбары и не понятно программистам с ООП профдеформацией. :)

    • @RomanL321
      @RomanL321 ปีที่แล้ว

      ООП профдеформация это интересно))) всё под неё пытаются подтянуть, иногда усложняя код до нельзя...

  • @jossefal1957
    @jossefal1957 4 ปีที่แล้ว

    Хорошее объяснение, как обычно лайк

  • @makskors5002
    @makskors5002 3 ปีที่แล้ว

    TDD очень интересно!

  • @VoroninPavel
    @VoroninPavel 4 ปีที่แล้ว

    Хе-хе, люблю этот пример с квадратом и прямоугольником. Только он еще веселее. Если ввести иммутабельность с втиле старого доброго ФП и после вызова любого "мутирующего" метода возвращать экземпляро нового объекта, то квадрат-таки можно сделать проямоугольником, не нарушая принципы ООП ;-)

  • @sfoxer
    @sfoxer 4 ปีที่แล้ว

    Лучший препод =) Что бы мы без вас делали)

  • @victortamanov
    @victortamanov 4 ปีที่แล้ว +2

    Про TDD интересно будет посмотреть.

  • @topalidinka
    @topalidinka 3 ปีที่แล้ว +4

    Я вас обожаю. Вы один из самых интересных и умных людей, которых я знаю) спасибо за знания и ваш юмор ☺️

  • @dmitry_shelemekh
    @dmitry_shelemekh 4 ปีที่แล้ว

    Крутотенюшка!

  • @samirsalimkhanov3554
    @samirsalimkhanov3554 4 ปีที่แล้ว +13

    Надо убрать бумагу между маркером и доской, потом писать. Я так думаю))) спаисбо за видос

    • @YuretsUA
      @YuretsUA 4 ปีที่แล้ว +2

      Это нарушает 1-й принцип SLP, каждому объекту своя зона ответственности, доска для того, чтобы бумагу удерживать, и бумага не рвалась под фломастером. А бумага уже для отображения текстовой информации, так что тут все грамотно...

  • @TheDaslord
    @TheDaslord 4 ปีที่แล้ว

    Сергей, спасибо за видео!
    Пожалуйста, снимите видео про возврат null, очень интересно, сам постоянно так делаю.

  • @dmitrinikolaev6986
    @dmitrinikolaev6986 4 ปีที่แล้ว +2

    Про TDD было бы очень интересно послушать!

  • @alexeiceglei9841
    @alexeiceglei9841 4 ปีที่แล้ว +1

    Юнит тесты интересны очень, особенно какие то хитрости, типо того же test first

  • @MrLobash
    @MrLobash 4 ปีที่แล้ว +1

    не ну тут лайк))

  • @Telemahk
    @Telemahk 3 ปีที่แล้ว

    По итогу - надо квадрат наследовать от прямоугольника или правильнее новый класс делать?

  • @gomer3894
    @gomer3894 4 ปีที่แล้ว +1

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

  • @newprim1
    @newprim1 3 ปีที่แล้ว +1

    Это самое лучшее объяснение принципа Лисков, что я встречал! Подписка однозначно

  • @ivanoviv1844
    @ivanoviv1844 ปีที่แล้ว

    Ну как тут не подписаться ну никак и лайк поствлю и все что угодно

  • @dmytromarchuk3023
    @dmytromarchuk3023 4 ปีที่แล้ว +3

    Ставлю лайк відразу! "Виріс" на відосах Сергія про Design Patterns, Clean Code, etc

  • @ArtemGaleev-w4t
    @ArtemGaleev-w4t 4 ปีที่แล้ว +2

    Раз уж вы сказали про наследование и попросили предложить что после СОЛИД рассказать, то предлагаю достаточно холиварную тему: наследование vs композиция. Заранее прошу прощения если вы эту тему уже поднимали

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  4 ปีที่แล้ว +1

      расскажу. Регулярно поднимаю эту тему на тренингах, надо и в отдельном видео рассказать

  • @alexei3366
    @alexei3366 4 ปีที่แล้ว

    можете записать видео почему метод не должен возвращать null?

  • @Lammax2012
    @Lammax2012 4 ปีที่แล้ว

    TDD - очень интересно!!!

  • @eligolin9947
    @eligolin9947 2 ปีที่แล้ว +4

    По моей оценке вся суть проблемы была не раскрыта.
    Наследование как "анти паттерн", основана на сложности соблюдение LSP принципа.
    Пройдёмся по примерам в этом ролике:
    1. Здесь Сергей рассказывает как плохо нарушать LSP принцип и к чему это может привести. Но дело не в том что его нельзя явно нарушать (это и так понятно), а в том что его очень сложно соблюдать.
    2. Сергей здесь спасибо вам за альтернативное определение LSP (оно добавляет глубины понимания!) хотя по моей оценке примеры всё равно слабы.
    3. По моей оценке этот пример вообще не об этом. Здесь проблема не в соблюдении или несоблюдении LSP, а в отсутствии инкапсуляции. Это был хороший пример того что лучше писать иммутабильные классы а setters/getters могут раскрыть зачастую внутреннюю структуру класса.
    С точки зрения наследования - это как раз один из немногих примеров где наследование является корректным. Наследования квадрата от прямоугольника является математически правильным и хорошо обоснованным с точки зрения качеств квадрата по отношению к качествам прямоугольника.Если бы состояние этих классов задавалось только при помощи конструктора, то никакой проблемы не было бы.

  • @homo-ergaster
    @homo-ergaster 4 ปีที่แล้ว

    Вот что интересно, базовые классы Java нарушают LSP совершенно без стеснения. Попробуйте, например, сделать так:
    Map map = Map.of("a", 10, "b", 20);
    map.put("c", 30);
    и охренейте от того, что вам прилетит Exception в Runtime. При том что вся эта лабуда прекрасно скомпилируется. Когда-то налип с этим делом по незнанию, пришлось в довольно большом пакете искать где я делал Map.of и переделывать на new HashMap.

  • @Ardolynk
    @Ardolynk ปีที่แล้ว +1

    Разве mock не должен лежать в модуле test, недосягаемом для основного кода?

  • @dmitriimolchanov4971
    @dmitriimolchanov4971 3 ปีที่แล้ว +3

    На примере mock, можно ведь для неиспользуемых методов оставить имплементацию парент класса, если это, конечно, не абстрактый класс или мы не имплеменим интерфейс. Хотя тут уже тогда нарушение как раз второго принципа-необходимо использовать интерфейс, или я что-то упустил?)

  • @halgerdka9287
    @halgerdka9287 4 ปีที่แล้ว

    про пример с квадратом. что мешает переопределить только метод getSquare() return a*a ? и вообще не трогать b

  • @Brick87Game87
    @Brick87Game87 4 ปีที่แล้ว +1

    супер, спасибо!

  • @AAAnatoly
    @AAAnatoly 4 ปีที่แล้ว +29

    Юнит-тесты очень интересны. По сути, я самоучка, и до юнит-тестов не дошёл, а начинать страшно

    • @yatigrrrrrrr
      @yatigrrrrrrr 4 ปีที่แล้ว

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

    • @k_v_i_i
      @k_v_i_i 4 ปีที่แล้ว +4

      Ничего там нет страшного

    • @pgriggs1299
      @pgriggs1299 4 ปีที่แล้ว +3

      @@yatigrrrrrrr Mockito и JUnit обязательно нужно знать джуну, также будет в разы круче, если код, например, в пет-проектах будет протестирован, потому что не протестированный код = нерабочий код

    • @r2d2925
      @r2d2925 4 ปีที่แล้ว +1

      Что сложного, вызвал метод, передал тестов данные, и сравнял с заранее верным ответом. Это примитив, но смысл таков. Модульные тесты сложнее, но тоже эмалируешь роботу кода и сравниваешь с подготовленным ответом.

    • @John_602nd
      @John_602nd 4 ปีที่แล้ว +1

      Ничего страшного совершенно, с ними другая проблема, что их ленятся писать. В Java все юнит тесты: @Before, @Test, assert(Equals/That/...)
      Если прочитать как это работает, то... Это в целом всё. А прочитать можно в первой же статье в гугле по запросу "Java UnitTest"

  • @haqon2k
    @haqon2k 4 ปีที่แล้ว +1

    В целом, неплохо рассказано, конечно. Я бы добавил в формат реальный кейс с кодом, примеров нарушений принципа в системных библиотеках (в той же Java нарушения лисков достаточно). Ещё не затронута тема ковариантности и контравариантности.
    Иии что значит нельзя возвращать null из методов? Это абсолютно нормально и даже нужно. Естественно, с документацией. Или когда ваш язык поддерживает нормальные nullable типы - null как отдельный тип данных.

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  4 ปีที่แล้ว

      нельзя возвращать null, это очевидно

    • @haqon2k
      @haqon2k 4 ปีที่แล้ว

      ​@@SergeyNemchinskiy Если вы имеете ввиду принцип Лисков, то и тут не соглашусь, всё зависит от контракта, предоставляемым базовым типом, если там подразумевается null, то можно.
      А если вы имеете ввиду вообще, в целом, то и тут неясна ваша идея. В некоторых случаях, действительно, есть лучше способ показать отсутствие данных. Например, в .NET - try pattern, когда возвращаемое значение - bool, показывающее результат операции, а данные возвращаются через ссылку одним из аргументов. Также в .net ввели nullable reference types, с помощью которого явно видно, где тип может быть null, а где нет.

    • @0imax
      @0imax 4 ปีที่แล้ว

      Я бы предпочёл получить из метода пустой список вместо null, прописанного где-нибудь в дебрях в документации.

    • @haqon2k
      @haqon2k 4 ปีที่แล้ว

      0imax Касаемо чего то перечисляемого, да, тут лучшим способом будет вернуть что то пустое, но существующее. И то стоит понимать, что могут быть моменты, когда нужно уметь различать отсутсвие самого списка и отсутствие в списке вообще кого то. Но обычные объекты, возвращаемые аля GetUserById, GetActualPlayerConnection и прочее - здесь лучшим способом заявить об отсутствии чего то только null, никаких throw

    • @0imax
      @0imax 4 ปีที่แล้ว

      @@haqon2k а по мне так лучше кинуть нормальный exception и обработать его, чем возвращать null:
      Во-первых, правильно названный exception сразу даёт информацию о причине "поломки". А во-вторых, таким образом можно обработать ситуацию, когда причин отсутствия объекта может быть несколько, как с тем же connection.

  • @vincentvega1903
    @vincentvega1903 4 ปีที่แล้ว +1

    I love you Nemchinsy so bad

  • @artemboiarshinov
    @artemboiarshinov 4 ปีที่แล้ว

    Немного про моки, раз уж Сергей про них заговорил.
    Чтобы замокать только строго определенные методы стороннего компонента, вызывающегося в тестируемом коде, можно использовать библиотеки типа Mockito или PowerMock, вместо того чтобы самостоятельно писать mock-реализацию этого компонента. Это стандартное решение, все так делают.
    Есть еще идея Егора Бугаенко: для каждого компонента в его интерфейсе писать fake-реализацию этого интерфейса, которая будет использоваться в тестах всех зависимых компонентов. Это похоже на то, о чем говорит Сергей Немчинский, но ответственность за написания мока берет на себя не разработчик клиентского кода, а разработчик компонента. Соответственно разработчик компонента обязан реализовать все методы этой fake-реализации. Немного утопическая идея, но она решает проблему хрупкости, присущей тестам, написанным с помощью Mockito.

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  4 ปีที่แล้ว

      то, что Бугаенко не знает слова Stub и вместо этого придумывает свои термины - не удивлен

    • @artemboiarshinov
      @artemboiarshinov 4 ปีที่แล้ว

      @@SergeyNemchinskiy Его основная идея заключается в том, что эти заглушки должны быть написаны в java-файле предоставляемого интерфейса. Мол это позволит пользователям вашей библиотеки не писать заглушки самостоятельно, что уменьшит дублирование кода на планете))
      А так мне и самому Егор Бугаенко не нравится, слишком уж он хайпожористый

  • @zapplay
    @zapplay 4 ปีที่แล้ว +1

    Хотелось бы увидеть видео о том почему нельзя возвращать null

  • @gromovoy1987
    @gromovoy1987 4 ปีที่แล้ว +1

    Харизматичный

  • @ЕвгенийЛапин-о4т
    @ЕвгенийЛапин-о4т 4 ปีที่แล้ว

    Ну вот отнаследовался я от Rect, сделал Square. На свойство b забил, переопределил метод getSquare, где работаю только с a. Ещё переопределил геттер/сеттер b, чтобы он работал с a вместо b. Работать будет, и даже тесты не рухнут скорее всего. Но плохо то, что есть лишнее свойство b, плохо то, что неочевидно работают геттеры/сеттеры b. Принцип именно в том, что не должно быть лишних свойств и неочевидного поведения?

    • @0imax
      @0imax 4 ปีที่แล้ว

      Принцип в том, что если подсунуть Square (в вашем случае) вместо Rect, то поведение не должно измениться. А оно изменится, причём с нарушением здравого смысла. Это и есть нарушение принципа LSP.

  • @Leonardo-gd2iz
    @Leonardo-gd2iz ปีที่แล้ว

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

  • @torrvic1156
    @torrvic1156 3 ปีที่แล้ว +3

    Я просто офигеваю от того, какой Сергей потрясающий интеллектуал. Мне страшно смотреть его видео. Страшно от того, что голова может лопнуть от обилия деталей, но потом трясущейся рукой тянусь и нажимаю кнопку начала просмотра, а потом инфа кое-как укладывается под отличную и ровную мелодию под методичный голос Сергея…
    P.S. короче, как тупой я понял принцип LSP главным образом в том, что не должен наследуемый класс делать больше, чем его основной класс.

  • @alexanderlex-s933
    @alexanderlex-s933 4 ปีที่แล้ว

    Изучаю Java с нуля. Даром прошли 5 лет в 1С, ООП - это взрыв мозга ))))
    11:20 - я не могу использовать ООП в 1С, там только процедурный код - и да, я чувствую себя рукожопом, но за хорошую зарплату.

  • @AndriySydorka
    @AndriySydorka 4 ปีที่แล้ว +2

    Дядя Сережа, росскажи про Test first!

  • @zhanibekkaimuldenov8272
    @zhanibekkaimuldenov8272 4 ปีที่แล้ว

    Давайте про TTD и я не понял пример с квадратом, в итоге нельзя квадрату наследоваться от прямоугольника получается или что делать ?)

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  4 ปีที่แล้ว +1

      в итоге надо наследовать наоборот

    • @Selt3Z
      @Selt3Z 3 ปีที่แล้ว +2

      @@SergeyNemchinskiy стоило сказать об этом в самом видео

  • @kosatchev
    @kosatchev 4 ปีที่แล้ว +5

    Принцип на примере семьи Хилтон:
    class Hilton {
    Money manageHotel(Hotel h) {
    Money m = makeCustomersHappy(c);
    return m;
    }
    }
    class Paris extends Hilton {
    @Override
    Money manageHotel(Hotel h){
    Money m = sellHotel(h);
    return m;
    }
    }

    • @torrvic1156
      @torrvic1156 3 ปีที่แล้ว +1

      Отличная шутка про ведение бизнеса 😂

  • @tislambek
    @tislambek 4 ปีที่แล้ว

    Можете расказать в следующем видео о проекты спринга

  • @OlezhikChanal
    @OlezhikChanal 4 ปีที่แล้ว +1

    Раз пошла такая пьянка. Серию про паттерны жду. Буду смотреть и советовать всем.

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  4 ปีที่แล้ว

      Ну про паттерны я уже снял. Вот она foxminded.com.ua/grasp-gof-design-patterns-advanced-on-line-course/

  • @radikovichkz2470
    @radikovichkz2470 ปีที่แล้ว

    А как на счет предпочитайте композицию наследованию?

  • @olexkov4643
    @olexkov4643 4 ปีที่แล้ว +1

    Интересно все !!!!

  • @JackFastGame
    @JackFastGame 4 ปีที่แล้ว +1

    А что является клиентским кодом в Unity?

  • @mykola-rohoza
    @mykola-rohoza 4 ปีที่แล้ว

    На счет возврата налл из метода - очень интересно ваше мнение
    Чем вам неугодил Актив Рекорд и какие вы видете альтернативы (все так работать с объектом который можно собрать из кусков и сохранить достатолчно удобно)

    • @FrolOFF100
      @FrolOFF100 4 ปีที่แล้ว

      Нарушает srp со всеми описанными в предыдущих видео последствиями

    • @mykola-rohoza
      @mykola-rohoza 4 ปีที่แล้ว

      @@FrolOFF100 Да понятно, что нарушение, но оно всеобщее (для пыховых фрэймов во всяком случае) потому и интересно какую альтернативу Сергей предложит

  • @DeMoniaqGRANI
    @DeMoniaqGRANI 4 ปีที่แล้ว +1

    Можно делать ООП и без наследования, через реализацию интерфейсов

    • @DeMoniaqGRANI
      @DeMoniaqGRANI 4 ปีที่แล้ว

      Влад Солнцев так через интерфейсы, минуя наследование, полиморфизм и делается. Главные парадигмы инкапсуляция и полиморфизм. Конечно можно с натяжкой сказать, что реализация интерфейсов это тоже наследование по сути...

    • @0imax
      @0imax 4 ปีที่แล้ว +1

      @@DeMoniaqGRANI А можно и без натяжки, поскольку это по сути наследование от full abstract класса))

  • @HaiIag
    @HaiIag 4 ปีที่แล้ว +1

    Я таки дочекався )

  • @maxlich9139
    @maxlich9139 4 ปีที่แล้ว +3

    Клевое видео. Единственное что Сергей не рассказал: что тогда делать-то, если твоя реализация не поддерживает данный метод базового класса? Я такое видел и не только в тестах и моках (и там да, бросались эксепшены; и вроде бы это даже было в каких-то известных либах)

  • @FrolovDaniil
    @FrolovDaniil 4 ปีที่แล้ว +9

    Можно ещё про DRY, KISS, YAGNI

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  4 ปีที่แล้ว +3

      уже в планах

    • @FrolovDaniil
      @FrolovDaniil 4 ปีที่แล้ว +2

      @@SergeyNemchinskiy Смотрю Вас из интереса уже наверное больше года, когда ещё начинал знакомиться с Java, сейчас вообще Python разработчик. Так вот качество видосов стало на порядок выше, видно, что развиваетесь. Так держать! Пожалуйста, подумайте по поводу маркерной доски, а то эти шуршания маркера по бумаге некоторых приводят в ужас (меня например).

  • @woodzimierz9621
    @woodzimierz9621 4 ปีที่แล้ว

    Интересует на сколько сейчас актуально Eclipse RCP разработка? Сейчас вообще кто ни будь десктопы разрабатывает?

  • @chocolazerboom7389
    @chocolazerboom7389 4 ปีที่แล้ว +46

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

    • @ESTechnonet
      @ESTechnonet ปีที่แล้ว +3

      А еще больно - звук маркера скрипучий.