Что такое SOLID? Простыми словами о принципах ООП

แชร์
ฝัง
  • เผยแพร่เมื่อ 13 ก.ค. 2024
  • Подробно разберём все ООП принципы SOLID с примерами из Unity и C#. Также проведём и небольшой разбор кода.
    • 🖤 GitHub: github.com/MeeXaSiK
    • 🖤 VK: nighttraincode
    • 🖤 Telegram: t.me/nighttraincode
    • 🖤 Instagram: / the.meps_
    Все принципы объектно-ориентированного программирования SOLID:
    1. Принцип единой ответственности [SRP]
    2. Принцип открытости/закрытости [OCP]
    3. Принцип подстановки Барбары Лисков [LSP]
    4. Принцип разделения интерфейсов [ISP]
    5. Принцип инверсии зависимостей [DIP]
    • 🖤 Поддержка канала:
    www.donationalerts.com/r/nigh...
    • Таймлайн:
    00:00 ► Вступление
    00:24 ► Что такое SOLID?
    01:32 ► Single Responsibility Principle
    03:25 ► Полезный Code Review
    06:49 ► Open-Closed Principle
    08:35 ► Liskov Substitution Principle
    10:27 ► Interface Segregation Principle
    12:13 ► Dependency Inversion Principle

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

  • @psy_gamer
    @psy_gamer ปีที่แล้ว +19

    Жаль, что когда устроился на работу не было такого простого объяснения SOLID) В итоге пришлось изучать его досконально, а теперь просто приятно послушать про принципы и освежить знания в памяти!

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

      Ахах, немного жиза, спасибо)

  • @OG_LEB
    @OG_LEB 5 วันที่ผ่านมา +1

    Еду на собес и смотрю твой видик. Кайфанул в процессе ❤

    • @NightTrainCode
      @NightTrainCode  5 วันที่ผ่านมา

      @@OG_LEB Удачи на собесе!)

  • @max_monax
    @max_monax หลายเดือนก่อน +1

    отличный материал, действительно очень мало кто говорит про архитектуру кода на примерах да ещё и в GameDev-е.
    PS: на этапе про InputService было бы очень к месту применить и рассказать про Dependency Injection.

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

    Редко видел что бы халф-лайф приводили как пример. Честно говоря, приятно когда про неё вспоминают)

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

      Одна из любимых игр)

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

      @@NightTrainCode так же)

  • @YACommunity
    @YACommunity ปีที่แล้ว +12

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

    • @lordent
      @lordent 4 หลายเดือนก่อน

      Не увидите, это та вещь которая нарабатывается только опытом с годами 🤷

  • @rimgro
    @rimgro ปีที่แล้ว +17

    отличный канал, в ру сегменте очень мало подобного, обычно весь контент заканчивается гайдами по типу: "Учимся открывать юнити за ЧАС" от хауди хо, а тут затрагиваются куда более сложные и интересные темы, которые иногда бывает довольно сложно понять, автору респект

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

      Ахахахха, с "учимся открывать юнити за час" орнул)
      Спасибо большое за теплые слова 😉

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

      @@NightTrainCode вот вам смешно, а я ведь был когда-то глуп и смотрел такие вот видео, но сейчас понимаю, что конечно все равно лучше базовый курс по юнити где-то купить и быстро всю основу понять. А автору как обычно респект, что пытаешься наш российский ютуб правильному коду обучать, очень много полезного узнаю из твоих видео, хотя если честно сложновато бывает понять, что на экране происходит, пересматриваю по несколько раз и на паузу ставлю. Не помню есть ли у тебя видео про abstract классы и readonly, а то я уже много где их видел, но все никак не пойму как именно их применять (если вдруг знаешь хорошие видео буду рад рекомендациям).
      В любом случае, большое спасибо за видео)

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

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

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

      @@artsurock Все мы проходили чем море ужасного контента по юнити на ютубе...
      Abstract - обширная тема (но самом деле очень простая), а ключ readonly разрешает устанавливать значение полю только через конструктор, либо через оператор равенства при её объявлении

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

      @@NightTrainCode а разве в unity нет конструктора?

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

    Как понять, что человек действительно разбирается в своей области? Даже самые сложные вещи он сможет объяснить и пятилетнему ребёнку. Остальные псевдо-программисты очень любят забросать терминами не пытаясь объяснить сути. Ты сумел объяснить все принципы SOLID за 11 минут когда как у других горе-блогеров на это могло уходить до часа. Отличная работа!

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

      Спасибо, рад помочь)

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

    6:00 насчёт множителя урона, пример, в принципе, хороший. Но более идеальным примером был бы паттерн декоратор. Так как наследование статический связывает систему демеджа и множитель, а декоратор позволяет расширять динамически до бесконечности в различных комбинациях) Не пытаюсь показать, что я умнее автора этого видео. Пусть это будет зацепкой остальным, чтобы начали копать в нужном направлении. Автор, вы топчик!

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

      Хотел бы дополнить, что декоратор как раз отвечает за принцип открытости-закрытости. Так как он расширяет функционал основного класса без его изменения.

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

    Хоть я всё это слышал и знаю, но повторение - мать учения :D

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

    Наткнулся на видео абсолютно случайно, и уже на 2-3 минуте подписался и поставил лайк, притом что обычно я на лайки скупой.
    Это лучший контент по программированию в юнити, который я видел. Каждый описанный случай там - это реальная болячка моих давних начинаний.
    В дополнение к последнему, что касается управления, хочется рассказать смотрящим об еще большем упрощении, которого нет и не должно быть в этом видео, потому что оно никак не касается солид. Можно даже не менять в конечном классе типы инпутов для каждой платформы перед каждым билдом, а добавить директивы вроде #UNITY_ANDROID в этот же класс и в логику отрисовки кнопок для сенсорных устройств, логику aim assist для геймпадов и т.д., и тогда можно будет без изменений собирать один и тот же проект для всех платформ.
    Огромное спасибо автору за видео и удачи в продвижении канала. Уверен, что удача ему с таким контентом не понадобится, потому что человек разбирающийся сразу скажет, что конкурентов у этого канала просто нет.

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

      Привет, спасибо большое, очень приятно читать твой комментарий)
      Да, ты всё по фатку написал. Можно использовать директивы или Conditional, но отношения это к SOLID не имеет. Ещё у нас может быть другая похожая ситуация, но уже не с управлением персонажа, где можно код в зависимости от платформы выбирать, а что-то другое, где как раз идеально впишется этот способ.

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

    Отличный контент, такого крайне не хватает на ютубе, спасибо!

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

      Спасибо большое)
      На здоровье

  • @EvgeniyZhukov-lt8rq
    @EvgeniyZhukov-lt8rq ปีที่แล้ว +1

    С большим интересом посмотрел, благодарю🤝

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

    Разбор SOLID как нельзя кстати. На прошлом интервью про liskov substitution principle и DIP не смог нормально рассказать, из за чего словил отказ. Впереди еще несколько интервью. Но теперь все встало на свои места. благодарю. Буду рекомендовать это видео знакомым + подписчикам канала когда разморожу свое хобби и сделаю рестарт канала. 😘Еще раз благодарю за труды.

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

      Спасибо большое, рад помочь)

  • @gusssduck4189
    @gusssduck4189 8 หลายเดือนก่อน +1

    Краткая и понятная информация ,благодарю

  • @user-yn6np8xi7k
    @user-yn6np8xi7k ปีที่แล้ว +1

    Отличный видос! Всё просто с простыми примерами. Спасибо!

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

      На здоровье, спасибо)

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

    Спасибо, твои видео очень помогают )

  • @pieceofsnitcrappy2800
    @pieceofsnitcrappy2800 9 หลายเดือนก่อน

    Как приятно видеть грамотно написанный код

  • @user-fp2bj5uk7h
    @user-fp2bj5uk7h ปีที่แล้ว +1

    Спасибо за полезный контент!!! Продолжай в том же духе, успехов!!!)

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

      На здоровье, спасибо большое)

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

    Спасибо вам за урок! Очень полезно! 👍

  • @user-kx7tw8wy8b
    @user-kx7tw8wy8b ปีที่แล้ว +1

    Очень полезная штука, спасибо)

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

    ЭТО ШЕДЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕВРРРРРРРРРР!!!!

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

    отличное объяснение!

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

    На столько понятного и интересного контента, еще и с приятным голосом, надо поискать. Очень рад, что нашел ваш канал. Спасибо вам большое за то, что вы теперь есть на просторах ютуба :3
    P.S. В одном из предыдущих видео была вставка из отдыха на даче. Очень порадовала. В такие моменты чувствуешь, некую связь с автором видео, понимая, что он тоже человек. Ну и вспомнил свои приятные моменты с подобных выходных с друзьями.

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

      Большое спасибо, на здоровье! А мне очень приятно читать Ваш комментарий)
      Ахах, значит мне надо и дальше вносить разнообразие в видео вставками из жизни, если они в тему 😄
      Кстати, я с такими мыслями и делал ту вставку, что Вы описали в постскриптуме)

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

      ​@@NightTrainCode
      Буду и дальше радовать Вас комментариями, просмотрами и лайками :3 Уже порекомендовал ваш канал нескольким знакомым. Теперь уже не только мне одному интересно, чему вы будете нас учить в следующий раз!
      Я рад, что ваша вставка оказала именно тот эффект, который вы закладывали. Признаюсь честно, в какой-то момент появилось желание поучаствовать в том веселье :)

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

      @@dzammboo Спасибо большое, безумно благодарен)
      Ахах, будете в Красноярске, залетайте к нам на дачу 😹

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

      @@NightTrainCode Спасибо) Обязательно сообщу, как буду проездом! :3

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

      @@dzammboo Окей)

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

    Супер контент!

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

    А я сначала не поверил что за 15 минут мне весь солид расскажут;) :D

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

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

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

    Только что хотел узнать про это и тут уведомление

  • @karimkimsanbaev7932
    @karimkimsanbaev7932 8 หลายเดือนก่อน +2

    Принцип инверсии зависимостей (D) не так объяснил, точнее пример не тот.
    Инверсия зависимостей, это парадигма инверсии управления.
    То есть вместо того, чтобы внутри класса или метода обращаться к другому классу/объекту - прямое управление. Мы прокидываем ссылку на объект в конструктор/метод и используем его - обратное управление.
    Если прокидываемая ссылка будет абстракцией/интерфейсом - получаем, что нижние слои (конкретные реализации), зависят от верхних слоев абстракции (интерфейсы).
    И тут уже получается возможность делать управления для разных платформ удобно. Но само по себе это некорректный пример Dependency Inverson.
    Контент приятный, подача отличная, спасибо)

  • @PS-vj6jz
    @PS-vj6jz ปีที่แล้ว +1

    Лайк есть, подписка тоже.

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

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

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

    лайк и коммент в поддержку канала!

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

    Немного провокационных вопросов для размышления (собственно, люблю на собеседовании в определенном контексте задать):
    1. Согласно приниципу разделения интерфейсов, класс реализует несколько интерфейсов. Например, в видео 11:50, класс Shotgun реализует IReloadableWeapon и IAlternateAttackWeapon. Не нарушает ли это первый принцип - единственной ответсвенности? Ведь, теперь у Shotgun две ответсвенности: реализация основной аттаки согласно первому интерфесу и реализация альтернативной атаки согласно второму интерфейсу.
    2. Похожий вопрос, но всегда можно задать к любому классу, у которого в контракте есть два публичных метода. У класса Pistol есть два метода: PerformAttack() и Reload(). Не нарушает ли это принцип единственной ответсвенности? Ведь теперь класс Pistol ответчает как за атаку, так и за перезарядку оружия - две ответственности.

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

      Ой, а как это меня на собеседование угораздило?)
      1. Нет, потому что оружие на то и оружие, чтобы у него была обычная атака
      2. По такой логике можно класс Microwave разделить на классы EnableMicrowave, DisableMicrowave и т.д., а это маразм)

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

      И благодарю за интересные вопросы)

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

      @@NightTrainCode а это не собеседование ) А вопрос ко всем: где та грань единственной ответсвеннности? Именно в этом и подвох: порой принцип единственной ответсвенности возводят в абсолют, а порой трактуют слишком широко.

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

      @@HizusHiz А никто не знает)
      Кто как хочет, так и...

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

      @@NightTrainCode Я себе в этом плане всегда задаю вопрос на перспективу: потребует ли бизнес (или геймдизайнер, если говорить про игры) в рамках конкретной сущности каких либо изменений или потребуется альтернативная сущность? Ответ на этот вопрос дает понимание, где надо вводить принцип единственной ответсвенности... Хотя и не всегда удается "угадать" ))

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

    Thank You Bro , Go ahead !!!

  • @user-hq2wg8pg1l
    @user-hq2wg8pg1l ปีที่แล้ว +2

    спс

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

    Cool

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

    Теперь все паттерны осталось объяснить

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

      Ахах, ага. А ещё принципы KISS и PIDOR)

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

    В UnitDamageable на 5:24 можно же было реализовать интерфейс IDamageable, внутри которого и был бы метод ApplyDamage(float damage)

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

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

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

      На здоровье)
      По про билдеру не планировал, год уже им не пользовался, но в идеи для видео запишу

  • @user-ps7fh4dx7k
    @user-ps7fh4dx7k 4 หลายเดือนก่อน

    Мне показалось по нарративу из видео, что принцип L и I очень схожи , можете объяснить ?

  • @krasav4ikmix
    @krasav4ikmix 7 หลายเดือนก่อน

    Коммент

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

    как такой левел делать на 1,45

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

      Купить в ассет сторе)

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

    Слишком тихие ролики

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

    ну так что это такое

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

      Виталя, фейсит пошли

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

    Ценю Ваш труд, но по SOLID материала и так завались. Вбиваю в поиск ютуба и вижу, что туториалы уже есть у каналов:
    Sunny Valley Studio
    Dapper Dino
    Jason Weimann
    Udeck - Чертог геймдева
    Infallible Code
    И это только с привязкой к unity.

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

      Спасибо)
      Да, верно! Пожалуй, удалю видосик 😹

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

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

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

    Боже, какой ужасный код... Событийно ориентированное программирование пытаются выдать за ООП.
    Наличие паблик полей не заставляет вас задуматься о том, что вы нарушаете Single Responsibility Principle, вынося тем самым логику нанесения урона за пределы объекта здоровья?
    Вот это же решение, но ОПП:
    1. в классе UnitHealth создаём private float _health
    2. создаём метод ApplyDamage(float damage)
    3. если нам надо куда-то нарисовать здоровье, то создаём для класса UnitHealth метод DrawHealth(ITextOutput textOutput)
    4. в интерфейсе ITextOutput создаём метод Draw(string text), который уже сам решит на какой канвас выводить переданный ему текст
    5. для класса UnitHealth создаём интерфейс IHealth, который имеет методы ApplyDamage(float damage) и DrawHealth(ITextOutput textOutput)
    Вот что такое ООП, а не то что показано в ролике.

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

      Если есть вопрос как же потом сообщить герою, что ты умер, то в конструкторе класса UnitHealth необходимо передать ссылку на интерфейс IDamageable, а юниту унаследовать его.

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

      Начнём с того, что там у нас не публичные поля, а публичные свойства. Разницу можете почитать в интернете :)
      А пихать логику Damageable и DrawHealth в класс UnitHealth - вот это, случайно, не нарушение принципа о единой ответственности?)

    • @user-vz5vw6cg9s
      @user-vz5vw6cg9s ปีที่แล้ว +2

      А ООП запрещает нам пользоваться событиями или я чего-то не знаю?

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

      @@NightTrainCode 1. Это вообще не играет роли. Любые паблик поля, как бы вы их не называли, протектед, не протектед, они сообщают информацию об объекте, грубо говоря разглашают его состояние. Это нарушение инкапсуляции. Объект не должен делиться своим состоянием, так как внешний код будет на него завязываться и это будет нарушать SRP, так как уже внешний код, прямо как у вас в примере будет заниматься тем, что будет изменять состояние объекта напрямую, а не через регламентированный метод. Если для вас это не проблема, то вы дилетант и скорее всего выше чем на джуна вас не возьмут.
      2. Когда мы даём нашему объекту Health метод DrawHealth, а в параметр передаём ссылку на объект, которому нужно сообщить об изменении, никакой ответственности по отрисовке класс не берёт, он только сообщает значение объекту, который занимается выведением значения. Тут всё ровно. Объект который рисует передаётся в ссылке, а здоровье только уточняет что именно отобразить, при этом не раскрывая своё состояние внешнему классу.

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

      @@YooPita Ок)

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

    Главное, чтоб кто-то из твоих подопечных не додумался реализовать в Shotgun отдельно IRelodableWeapon.PerformAttack и IAlternativeAttackWeapon.PerformAttack. Это было бы странно 🙃