SOLID, 1.3 LSP - Liskov Substitution Principle Принцип подстановки Лисков - С#, Unity

Поділитися
Вставка
  • Опубліковано 17 лис 2024

КОМЕНТАРІ • 50

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

    Невероятно доступное объяснение! Спасибо большое!

  • @Ilja.Kiriljuk
    @Ilja.Kiriljuk 3 місяці тому +1

    По мне дык самый понятный принцип. Когда-то давно сам пришёл к тому что нужно соблюдать эти правила

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

    У меня аж флэшбэк к тем временам, когда я читал head first design patterns. Особенно про утку

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

    Спасибо, легко и понятно. Жаль мало просмотров для того контента.Повезло, что попало в рекомендации !

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

      Спасибо, да этому каналу вчера 2 недели исполнилось. Постараюсь наполнить его полезными уроками, авось со временем просмотры накапают)

  • @Igor-Demchuk
    @Igor-Demchuk 24 дні тому

    Это потрясающе, спасибо большое!

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

    Спасибо! Объясняете сильно лучше чем кто либо! Даже LSP и DIP стали понятней :)

  • @alexeysmirnoff7637
    @alexeysmirnoff7637 9 місяців тому +2

    Первое понятное объяснение. Спасибо огромное.

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

    Спасибо тебе. Я и раньше использовал этот подход в своем коде, но сука не мог понять что такое LSP

  • @ШонМелтон
    @ШонМелтон Рік тому +2

    Отличное видео! Спасибо. Вы очень хорошо и интересно доносите информацию.

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

    очень хорошо объяснено, уверен новичкам все кристально понятно, лайк

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

    Очень качественный видеоролик, помогает готовиться к экзаменам 👍👍

  • @VyacheslavTamplier
    @VyacheslavTamplier Рік тому +2

    Великолепные объяснения принципов. Спасибо.

  • @danilazakharov4034
    @danilazakharov4034 Рік тому +2

    Появился небольшой диссонанс от нескольких принципов, кажется будто они немного противоречат друг другу. Вот у нас есть Item, Sword, HealthPotion и мы хотим добавить Junk. Когда мы оставляем пустой метод Use, мы нарушаем LSP, но при этом соблюдаем OCP (не изменили базовый, поменяли поведение производного). Когда выводим Use в отдельный интерфейс, то смогли соблюсти LSP, но полностью похерили OCP, изменив базовый класс.
    Получается, тут дело в том, что нам изначально нужно было писать, чтобы не нарушить оба этих принципа? Но разве такое вообще возможно предугадать на 100%, что в будущем потребуется поменять, а что нет?
    P.S. Ну и пользуясь случаем, хотел сказать спасибо за уроки) Отличная подача, прекрасное объяснение материала и грамотно подобранные мемы, ну красотища

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

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

    • @ГеннадийШушпанов-д1ч
      @ГеннадийШушпанов-д1ч Місяць тому +1

      Вы не одиноки в своих сомнениях. Я тоже считаю что, OCP и LSP противоречат друг другу. Корень этого противоречия я вижу в том, что они, говоря про производные классы, используют разные модели: OCP -- расширение функционала, а LSP -- наследование (детализацию абстракции). Поэтому им вряд ли удастся одновременно следовать. Вот автор в своем примере перешел с наследования на расширение и LSP теперь не применим, поскольку мы не можем использовать производный класс на месте базового. Кстати, за кадром, и OCP пострадал. Раньше код использовал List, а теперь -- List.
      Тут автор писал, что OCP не жесткое правило. Я думаю, что весь SOLID, вопреки названию не жесткий. Рекомендации, не более.

  • @frogo513
    @frogo513 Рік тому +3

    Отличное видео. До этого сталкивался с непониманием проблемы, которую решает этот принцип. Спасибо за объяснение, теперь понимаю. Хотелось бы увидеть, как ты реализовал контекстное меню с действиями у разных предметов. Сам столкнулся с такой трудностью. Немного не понимаю, как обрабатывать в ui при наведении на разные предметы разные кнопки.

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

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

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

    Большое спасибо за видосы, очень познавательно.

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

    я вас обожаю ❤

  • @КорвинКори-б6у
    @КорвинКори-б6у Рік тому +1

    Замечательный контент и канал

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

    Спасибо!

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

    Круть!

  • @R193BK
    @R193BK 5 місяців тому

    Какой же ты крутой!

  • @Gileanify
    @Gileanify Рік тому +2

    Отличное видео, хотелось бы увидеть разбор более сложных кейсов с применением интерфейсов на практике в Unity. Насколько мне известно, там довольно много подводных камней, которые делают использование интерфейсов намного менее оправданным.

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

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

  • @USSR-Lenin-Stalin-Forever
    @USSR-Lenin-Stalin-Forever Місяць тому

    Есть тоже прикольное видео на тему оружия и итемов "Bob Nystrom - Is There More to Game Architecture than ECS?" Там структура item содержит интерфейсы Attack, Use, Defence и если хочешь что бы твой предмет можно было юзать просто дай ему этот класс а если не хочешь то присвой условно NoneUse . В общем тоже советую к просмотру

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

    Отличный ролик, но я не очень понимаю как использовать этот принцип, когда в проекте много интерфейсов. Допустим у меня есть класс BaseItem с методом Collect и интерфейсы в духе IUsable, IDiscardeable, IDestroyable, ISellable и тд. Производные класса BaseItem по идее могут наследовать все эти интерфейсы разом, но как тогда их хранить? создавать по списку на каждый интерфейс? или создать один список BaseItem и при помощи if esle проверять наследуется ли экземпляр класса от нужных интерфейсов?

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

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

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

      @@sergeykazantsev1655 Спасибо!

  • @РНС_Саакашвили

    скажите пожалста, а как после добавления интерфейса пройтись циклом по списку ? . . . только типизировать список . . . а по-другому нельзя без ????????

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

      на 10:03 на видео как раз это и делается. Создается три объекта разных реализаций и они добавляются в список usableItems. И потом по этому списку мы идём циклом.

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

    а можно было вместо интерфейса сделать класс UsedItem, в него засовываем Use() из Item и уже от него наследоваться мечу и зелью?

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

      Можно, но нужно ли? Тут вопрос в разнице между абстрактным классом и интерфейсом. Если помимо метода Use вкупе идут какие-то параметры, то можно. А так особого смысла нет

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

      @@sergeykazantsev1655 тогда что лучше: один абстрактный класс с несколькими методами или на каждый метод по интерфейсу?

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

      сам того не зная ISP использовал)

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

      Типа того, да. Считаю, что правильный ответ - это поступать по ситуации. В зависимости что за поведение, есть ли какие-то свойства и тд.

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

      @@sergeykazantsev1655 а вот это уже мидлом нужно быть, чтобы чувствовать

  • @РНС_Саакашвили

    вопрос такой . . . между 8:45 и 9:00 . . .цитата: "если поставить любой производный класс" . . . а куда "поставить" ? . . . тут наверное какой-то текст пропущен . . . прослушайте пожалуйста сами ваш текст

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

      Цитата на 8:48 "И вот принцип LSP как раз говорит о том что нужно организовать архитектуру таким образом, чтобы если мы подставили ЛЮБОЙ производный класс, в том числе наш JunkItem, система должна отработать без поломок".
      Куда именно подставлять? Подставлять в систему где мы массово пробегаемся по предметам, причем к предметам мы обращаемся как к базовым классам.
      Чуть раньше в этом же видео я показывал скрипт где мы пробегались по видео (07:16 TestFirst и 08:18 TestSecond)

    • @РНС_Саакашвили
      @РНС_Саакашвили Рік тому

      @@sergeykazantsev1655 спасибо . . . за цитату

  • @scc-6
    @scc-6 5 місяців тому

    Блять, круто конечно...Но наследник IEnumerable ICollection является родителем ReadOnlyCollection в котором поля Add и Remove заткнуты исключениями. А это, типа, стандартная логика языка и нарушается LSP( ЛСП - Ползать)

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

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

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

    Что за странный пример? Use у мусорных предметов вполнее нужен. для вывода сообщение что игрок идиот

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

      Ну это токсичненько писать игрокам что они идиоты) лучше сделать так чтобы механика use была полностью скрыта для мусорных предметов)

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

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

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

      Ну вы как разработчик, а скорее даже как геймдизайнер вольны выбирать как вам больше нравится.
      Пример я привёл в рамках своей задачи, чтобы показать что такой случай может быть когда один из производных классов не корректно отрабатывает логику указанную в базовом классе и это и есть нарушение LSP
      Если у вас есть более наглядный пример нарушения LSP - я готов ознакомиться, никогда не против найти вариант получше, всё таки с момента видео год прошёл)

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

    Спасибо!