Нарушаем принцип подстановки Лисков и смотрим, что получилось

#soer #itubeteam
Основной канал для общения и публикации новых видео - Телегарм - t.me/softwareengineervlog
Спонсорство - donate.s0er.ru
Сайт платным контентом - soer.pro
Зеркало для видео Дзен Видео - zen.yandex.ru/id/5f578bdf22e2...
GitHub - github.com/soerdev
Чат для программистов - / discord
Группа ВК - codeartblog

Пікірлер: 162

  • @torburgmax
    @torburgmax3 жыл бұрын

    это видео понравилось. я хорошо на него реагирую.

  • @darkfateinc7333
    @darkfateinc73333 жыл бұрын

    Соер, я думаю все что касается принципов ооп и паттернов проектирования сто процентов будет интересно смотреть, особенно от такого про. Пасиба)

  • @maximkurbanov

    @maximkurbanov

    3 жыл бұрын

    Ты права.

  • @railsabbitovich408
    @railsabbitovich4083 жыл бұрын

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

  • @user-po3id7ee7n

    @user-po3id7ee7n

    3 жыл бұрын

    Стать программистом и быть программистом разные вещи)) Если ты не готов 2 дня искать баг в говнёвом коде твоих предыдущих коллег, до 6 утра сидеть латать дыры, потому что на релизе новой фичи ты обосрался и несколько десятков тысяч человек не смогли получить то, что им обещали и заказчик потерял уйму денег, учиться каждый день новому и не стоять на месте, а также всё прочее сопутствующее... ты конечно можешь попробовать) Если не горишь этим, а идешь только за деньгами или статусом или ещё чем-либо кроме личного интереса, разочарование не заставит себя долго ждать) А обучение будет мучительным) Говорю тебе как человек, свичнувшийся в бек-енд в 28 лет из вообще левой сферы деятельности)

  • @romanradchenko3569

    @romanradchenko3569

    3 жыл бұрын

    Похожее вы и так уже программист.

  • @user-ot5kt1fi3v

    @user-ot5kt1fi3v

    3 жыл бұрын

    @@romanradchenko3569 программист потому, что понимает лёгенький пример? Как-то странно)

  • @romanradchenko3569

    @romanradchenko3569

    3 жыл бұрын

    @@user-ot5kt1fi3v начинающий программист :) я понял вас, согласен, подчеркнул то что многие так и спонтанно начинают увлекаться программированием.

  • @egorkurilko2995

    @egorkurilko2995

    Ай бұрын

    @@user-po3id7ee7n Ну пи*дец, пойду умоюсь горькими слезами ))) в свои 43 годика. Программирование та же фабрика, где есть инженеры с мозгами и образованием, а есть "работяги", с образованием IT школы или курсов, которые и делают всю "черную" работу. Разделим же мух и котлеты! )

  • @user-lt2vd2ue2e
    @user-lt2vd2ue2e3 жыл бұрын

    Важное дополнение. Как скорее всего рассуждал программист, когда наследовал квадрат от прямоугольника? Он изучил предметную область и определил, что квадрат ЯВЛЯЕТСЯ прямоугольником, а раз так, то можно наследовать один от другого. Но с точки зрения LSP отношение ЯВЛЯЕТСЯ не отражают отношения подтипов, что и приводит к ошибке. Об этом пишет Роберт Мартин в книге «Принципы, паттерны и методики гибкой разработки на C#»: «Термин ЯВЛЯЕТСЯ слишком широк, чтобы служить определением подтипа. Правильное определение подтипа - ЗАМЕСТИМ, где заместимость определяется явным или неявным контрактом.»

  • @0imax

    @0imax

    3 жыл бұрын

    Ну так слово extends не просто так используется при объявлении наследования. Квадрат не расширяет прямоугольник :)

  • @artemeelemann317
    @artemeelemann3173 жыл бұрын

    Спасибо! За то, что раскрываете такие темы. В примерах, когда упоминается типизация, было бы, конечно здорово видеть примеры на TypeScript, потому что иначе получается мы говорим про интерфейсы, а в коде их нет И Рассматривать контрактное программирование без последних тоже, кажется недостаточным

  • @0imax

    @0imax

    3 жыл бұрын

    Можно было просто на джаве/C# пример показать, нагляднее было бы.

  • @user-qv4hn6qq4n

    @user-qv4hn6qq4n

    Жыл бұрын

    Понятие интерфейса шире одноименной конструкции из TypeScript и прочих похожих. Интерфейс - это то, через что вы взаимодействуете с некоей частью приложения, например как здесь - конструктор. Вот и получается, что interface'а нет, а интерфейс есть :)

  • @max_du_cheshire
    @max_du_cheshire3 жыл бұрын

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

  • @ILICH1980
    @ILICH19803 жыл бұрын

    еще такого контента, на практических примерах смотреть интересно

  • @igor_cojocaru
    @igor_cojocaru3 жыл бұрын

    Спасибо. Доступно. Ждем контактное програмирование

  • @TalkerTube
    @TalkerTube Жыл бұрын

    Спасибо! Поучил ответы на все вопросы!

  • @windxrunner
    @windxrunner3 жыл бұрын

    Да здравствует Соер, наш просветитель!

  • @Bunny-nr6qc
    @Bunny-nr6qc3 жыл бұрын

    Только начал читать "Совершенный код", дочитал до LSP и выходит видео про LSP. Кто такой же удачливый? Спасибо С0ЕР

  • @user-ic8zh9nw4m
    @user-ic8zh9nw4m3 жыл бұрын

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

  • @AlexeyGogots
    @AlexeyGogots3 жыл бұрын

    Сделали наследование и поучили проблему, использовали мутательность и получили проблему, очередной вариант фактори и получили проблему. Вывод: оопшники всегда найдут способ отстрелить себе обе ноги. :)

  • @0imax

    @0imax

    3 жыл бұрын

    Функциональщики всегда найдут повод потроллить ООПшников, даже если это очень толсто))

  • @AleksandrRasskazov
    @AleksandrRasskazov3 жыл бұрын

    Хорошее. Давай ещё про круг и овал :) Чтобы закрепить! Шутка.

  • @fallenangel1395
    @fallenangel13953 жыл бұрын

    Как по мне, проблема в том, что мы, изменяя поле width напрямую, раскрываем состояние объекта. Только сам объект должен знать, как нужно работать с его данными. В классе Rectangle должен быть метод "изменить ширину". В Rectangle этот метод должен изменять только поле width, а в Square этот метод должен быть переопределен: вместе с width будет меняться и height. Или переопределение методов тоже нарушает принцип подстановки Барбары Лисков?

  • @0imax

    @0imax

    3 жыл бұрын

    Я бы вообще не делал для квадрата отдельный класс, а пользовался везде rect-ом. Либо, если для квадрата нужно много уже готовых методов из прямоугольника, которые не хотелось бы копипастить - сделал бы композицию.

  • @user-qv4hn6qq4n
    @user-qv4hn6qq4n Жыл бұрын

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

  • @shluhogon_42
    @shluhogon_42 Жыл бұрын

    Уже во втором примере хоть и начальный квадрат не поменялся, но посчитали мы площадь не квадрата. Нельзя увеличить только ширину и сказать, что это квадрат. Это можно объяснить доходчивее и не растягивать на 15 минут

  • @realmanproject7529
    @realmanproject7529 Жыл бұрын

    видео - класс, нужно еще

  • @vitiok78
    @vitiok783 жыл бұрын

    Классика)) Что бы было хорошо сделать так, чтобы отличалось от многих других: Не только рассказать о проблеме, а ещё и предложить решение. Ведь такое использование Прямоугольника и Квадрата это "сферический конь в вакууме". Так вот, чтобы отличаться от всех остальных, было бы неплохо, если бы Вы эту задачу представили как конкретную практическую задачу, потом бы показали, почему такой подход не работает (что и было сделано в этом видео), но после этого ещё бы и показали, как изменить сам подход для решения этой практической задачи. Ведь её надо решать, бизнес не будет смотреть, что у вас Лисков не работает, ему нужно решение. Так вот, начинающему было бы неплохо показать, как с этим бороться грамотно, чисто. Ведь явно видно, что эти два класса родственные, что у них будет куча одинаковых методов. Вот надо было бы подвести программиста к пониманию, как выйти из этой ситуации. Итого: видео отличное, но можно было бы и ещё лучше

  • @OleguitoSwagbucks
    @OleguitoSwagbucks4 ай бұрын

    Интеграл для площади - красиво

  • @lamer7905
    @lamer79053 жыл бұрын

    Круто, такие видео заходят прям. Продолжай в том же духе, будет четко.

  • @IGBasov
    @IGBasov3 жыл бұрын

    Спасибо. Хорошо отреагировал на видео.

  • @archsapostle1stapostleofth738
    @archsapostle1stapostleofth7383 жыл бұрын

    Комментарий для поднятия просвещения в топы

  • @user-li7sm7ux2q
    @user-li7sm7ux2q3 жыл бұрын

    Самое крутое объяснение принципа подстановки! Так бы по всем принципам. Ещё хотелось бы увидеть видео про абстрактные методы и интерфейсы. Как правильно всем этим пользоваться

  • @user-vk2ws7dr1e
    @user-vk2ws7dr1e3 жыл бұрын

    Круто, теперь у меня яснота появилась с Лиской👍

  • @bigenough2122
    @bigenough21223 жыл бұрын

    Спасибо. Жду об контрактом)

  • @fellainthewagon7166
    @fellainthewagon71663 жыл бұрын

    Спасибо, стало чуточку легче

  • @user-xh5mp4rc6g
    @user-xh5mp4rc6g3 жыл бұрын

    Привет. Спасибо за видео. Было полезно. Можно еще таких примеров на другие принципы SOLID или паттернов GRUSP. Я бы посмотрел.

  • @sovrinfo
    @sovrinfo3 жыл бұрын

    Спасибо за видео.Коммент в поддержку!

  • @OlegMavlyutov
    @OlegMavlyutov3 жыл бұрын

    Эта серия роликов с объяснением SOLID на пальцах очень нравится! Куда более доходчиво чем в других источниках 😎👍

  • @TheNikki2009
    @TheNikki20093 жыл бұрын

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

  • @gennadiikhotovytskyi1579
    @gennadiikhotovytskyi15793 жыл бұрын

    Благодарю, интересно =)

  • @mikhailkh8560
    @mikhailkh85603 жыл бұрын

    Огонь! Наконец то я понял в чем же этот принцип заключается на самом деле.

  • @Shchyekinyanin

    @Shchyekinyanin

    3 жыл бұрын

    Тогда второе видео про пост/предусловия и инварианты Вам просто жизненно необходимо

  • @goshiketerevskiy2603
    @goshiketerevskiy26033 жыл бұрын

    Не особо гуру в ооп и паттернах, но когда начались все эти пляски с методами и конструкторами, сразу пришел к выводу "а нафига вообще было наследовать квадрат от прямоугольника". как оказалось не зря сомневался. опыт

  • @user-mh2fc5rs9r
    @user-mh2fc5rs9r3 жыл бұрын

    Даёшь контактное программирование!

  • @andreykhalepov8260
    @andreykhalepov82603 жыл бұрын

    Ждём с нетерпением продолжение!

  • @allepta9474
    @allepta94743 жыл бұрын

    Спасибо, стало понятнее)

  • @denisfrunza1040
    @denisfrunza10403 жыл бұрын

    Жду продолжения ✌️

  • @pavelkuprin5352
    @pavelkuprin53523 жыл бұрын

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

  • @entropyass
    @entropyass3 жыл бұрын

    Просто нужно было добавить сеттер и геттер на поле. Прямоугольник и квадрат различаются лишь тем, что у квадрата ширина и высота связаны(это одно и тоже). И методы для них как не масштабируй подходят. Пример: codepen. io/dkey26/pen/PoWvBRd

  • @ilyasharkov8257
    @ilyasharkov82573 жыл бұрын

    Спасибо за видео. Хорошо расрыт принцип подстановки Барбары Лисков. Очень много коментариев про наследование: что нельзя было квадрат наследовать от прямоугольника. Мне кажется, если бы javascript на уровне языка имел более мощную поддержку принципов ООП (инкапсуляция в смысле сокрытия данных) + свойства, то проблем с использованием методов базового типа применительно к потомку не возникло бы.Но из-за ограничений языка получился отличный пример.

  • @AlexanderSavchenko91
    @AlexanderSavchenko913 жыл бұрын

    спасибо ) отличное видео )

  • @VitaliyNET
    @VitaliyNET3 жыл бұрын

    Согласен, не нужно нарушать принцип. А в c/c++, за такое линеечкой по пальчикам еще добавить можно) Потому что, если таких Square, будет отрисовываться на экране 15-25 тыс (для OpenGL пустяк), то по памяти это будет в 2 раза больше. Потому что одно поле height лишнее хранится в памяти.

  • @0imax

    @0imax

    3 жыл бұрын

    И pragma pack не забыть :) правда, это уже совсем из другой оперы...

  • @hikkarion
    @hikkarion3 жыл бұрын

    Офигенное объяснение!

  • @Davie-gp2ej
    @Davie-gp2ej3 жыл бұрын

    Это видео понравилось, я подписался

  • @ptand5350
    @ptand53503 жыл бұрын

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

  • @alexneo5458
    @alexneo54583 жыл бұрын

    Видео супер, полезное. Хотелось бы правда, чтобы примеров было больше, т.е. несколько показывать. И желательно, давать некоторые примеры приближенные к реальным вещам, которые встречаются на практике в js, а не таким абстрактным.

  • @sergeys4732

    @sergeys4732

    2 жыл бұрын

    Создание кнопок разных, вот тебе пример

  • @MIXEL3D3
    @MIXEL3D33 жыл бұрын

    Спасибо, мистер

  • @ziroshibash7041
    @ziroshibash70413 жыл бұрын

    Офигенный видос, прям в тему, но немного не вовремя.

  • @orucqarayev4759
    @orucqarayev4759 Жыл бұрын

    спасибо

  • @hino2
    @hino23 жыл бұрын

    Ну я бы просто сделал класс для прямоугольника, где второй параметр в конструкторе был бы необязательным. И, если он отсутствует, то в высоту бы копировалась ширина.

  • @johnins1646
    @johnins1646 Жыл бұрын

    А что такое контрактное программирование? Это про интерфейсы или про рантайм лонику?

  • @Michael_Sh
    @Michael_Sh3 жыл бұрын

    Лайк не глядя.

  • @asnow8423
    @asnow84233 жыл бұрын

    Интересное видео)

  • @MrKelegorm
    @MrKelegorm2 жыл бұрын

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

  • @alexg9188
    @alexg91883 жыл бұрын

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

  • @dann1kid
    @dann1kid3 жыл бұрын

    Не досмотрев видево, мне кажется стоит закладывать в родительский класс возврат по количеству аргументов. Проблема наследования состоит в том, что если ты плохо спроектировал, то дальнейшие ветки зависят от рельс, на которые ты положил проект. А если ты поменял, то придется допиливать все наследование.

  • @BigCrus
    @BigCrus3 жыл бұрын

    го продолжение про контрактное программирование

  • @phil2964
    @phil29643 жыл бұрын

    👍👍👍

  • @vladhuz8423
    @vladhuz84233 жыл бұрын

    А большая проблема (я понимаю, что js, и мы ограничены в этом плане его реализацией с отсутствие private полей) не мутировать поля напрямую и сделать методы мутации внутри классов, после чего переопределить setWidth and setHeight для квадрата, в которых менять одновременно и то, и то? И на крайняк сделать expand method, который бы возвращал объект того или иного класса, в зависимости от того, равны стороны или нет?

  • @DjLeonSKennedy

    @DjLeonSKennedy

    3 жыл бұрын

    Если у тебя есть два типа А и B с общим интерфейсом и ты меняешь тип А на тип B, и программа работает верно, значит принцип L не нарушен, все

  • @tgeor293

    @tgeor293

    3 жыл бұрын

    Кстати, благодаря *_Public and private instance fields proposal_* в JS появятся приватные поля классов. А Chrome, Node и Babel уже поддерживают их.

  • @isidorob9901
    @isidorob99013 жыл бұрын

    На примере видео показано, что нарушив принцип мы не можем создать правильный builder и далее перекладываем возникающие проблемы (обработку ошибок) на других людей. Если мы не нарушим правило и создадим разные типы, то другим людям опять придется учитывать разные типы в своём алгоритме. Здесь вопрос - возможна ли какая-то генерализация чтобы не перекладывать проблемы далее? То есть как сделать универсальный билдер и рассчет площади для разных типов?

  • @artiomciobanu4689
    @artiomciobanu46893 жыл бұрын

    Классический пример)

  • @artkoorosawa6432
    @artkoorosawa64323 жыл бұрын

    Интересная тема. Чем больше вариантов видео о паттернах и принципах - тем больше будет осмысленности в этих вопросах. Очень хотелось бы избежать знания, наслышанности, заучивания и не использования.

  • @user-bl5qv3jy1l
    @user-bl5qv3jy1l3 жыл бұрын

    Это тема относится к архитектуре, дизайну или проектированию? Т.е. как мне найти книги про это?

  • @yuriymusienko9351

    @yuriymusienko9351

    3 жыл бұрын

    «Паттерны объектно-ориентированного проектирования» от банды четырёх

  • @Shchyekinyanin

    @Shchyekinyanin

    3 жыл бұрын

    Это относится к проектированию. Читайте про SOLID

  • @komodo9109
    @komodo91093 жыл бұрын

    Может я пропустил, а как насчёт количества вкладок?

  • @user-mu6bh9fc6x
    @user-mu6bh9fc6x2 жыл бұрын

    Soer твоё видео по Hex редактором у меня на ютубе не открывается, хотя до этого открывались

  • @isfland
    @isfland2 жыл бұрын

    А как правильно реализовать этот пример, не нарушая принцип подстановки Барбары Лисков? Сделать два независимых класса Rectangle и Square с независимыми методами расчета площади?

  • @user-ec7ne8rn5v
    @user-ec7ne8rn5v3 жыл бұрын

    А можно ли добавить 2 setter'а width и height для квадрата?

  • @0imax

    @0imax

    3 жыл бұрын

    Можно. И тогда придëтся думать над поведением в квадрате: игнорить один из сеттеров или менять w и h одновременно. В любом случае, базовый класс не подразумевает ни игнора одного из сеттеров, ни автоматического изменения размера той стороны, которую не трогали.

  • @user-nl7lu9yj6w
    @user-nl7lu9yj6w3 жыл бұрын

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

  • @WGDev
    @WGDev3 жыл бұрын

    * хорошо реагирует * интересно же ж

  • @Mike-hp3fh
    @Mike-hp3fh3 жыл бұрын

    Этот пример кстати наглядно показывает сильные недостатки ООП. Я даже простой квадрат и прямоугольник не могу написать с использованием ООП. Да и опыт показывает, что в подавляющем большинстве случаев я не могу в принципе создать нормальное дерево наследования, не нарушающее никаких принципов. А при создании базового класса мне нужно думать о том какими будут ВСЕ его дочерние классы, не будет ли проблем в будущем, что просто невозможно. Как могу я догадаться что кроме прямоугольника у меня еще будет квадрат, а потом еще и параллелограмм, а в коде уже все завязано на прямоугольники. Проблема ООП в самом его фундаменте - в объединении данных и логики и в строгом наследовании.

  • @user-kf1xn1dq9t
    @user-kf1xn1dq9t3 жыл бұрын

    Это все конечно замечательно,но как решить то проблемму квадрата и прямоугольника?

  • @0imax

    @0imax

    3 жыл бұрын

    Очевидно: не наследовать друг от друга :)

  • @user-kf1xn1dq9t

    @user-kf1xn1dq9t

    3 жыл бұрын

    @@0imax тогда код будет дублироваться, со всеми вытекающими последствиями. Прямоугольник и квадрат в прямом смысле слова используют одинаковую логику для всех операций над ними.

  • @0imax

    @0imax

    3 жыл бұрын

    @@user-kf1xn1dq9t Лучше использовать только rect. Но если почему-то позарез нужен отдельный класс для квадрата, можно использовать композицию.

  • @user-kf1xn1dq9t

    @user-kf1xn1dq9t

    3 жыл бұрын

    @@0imax я про общий подход к проблеммам такого плана. Тут недостаток примера в том что он не поясняет как надо ПРАВИЛЬНО (ТМ) поступать в такких ситуациях, когда вроде наследовать Y от X самое логическое что можно сделать чтобы не копировать километры кода, но потом из этого вылезает вагон проблем.

  • @0imax

    @0imax

    3 жыл бұрын

    @@user-kf1xn1dq9t попробовать использовать композицию вместо наследования - вполне общий подход. А уж конкретное решение сильно зависит от конкретного кода.

  • @a4y_m5r
    @a4y_m5r3 жыл бұрын

    И как же решить данную проблему? Делать разные классы для квадрата и прямоугольника?

  • @pavlomiklashevych1758

    @pavlomiklashevych1758

    3 жыл бұрын

    Ага. Добавив абстрактный класс "фигура", которому дать абстрактный метод для расчета площади.

  • @mik_zd

    @mik_zd

    3 жыл бұрын

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

  • @ibl8587
    @ibl85873 жыл бұрын

    реагирую!

  • @VladykaVladykov
    @VladykaVladykov3 жыл бұрын

    Наследование прямоугольника от квадрата решает проблему?

  • @davyzaebali

    @davyzaebali

    3 жыл бұрын

    нет

  • @TemkaGluck
    @TemkaGluck3 жыл бұрын

    Как будто, увлекшись SOLID, забыли про инкапсуляцию. Почему бы не перегрузить setWidth(newWidth) и описать корректное поведение и для прямоугольника, и для квадрата как наследника?

  • @bubblesort6368

    @bubblesort6368

    3 жыл бұрын

    Потому что это приведет к тем же проблемам что и метод mutation. Вместо 50 можно получить 25 и наоборот.

  • @TemkaGluck

    @TemkaGluck

    3 жыл бұрын

    @@bubblesort6368 mutation не приведёт. Попробуйте: #include class Rectangle { protected: int width, height; public: Rectangle(int w, int h) : width(w), height(h) {} int getWidth() const { return width; } virtual void setWidth(int newWidth) { width = newWidth; } int getHeight() const { return height; } virtual void setHeight(int newHeight) { height = newHeight; } long getArea() const { return width * height; } }; class Square : public Rectangle { public: Square(int w) : Rectangle(w, w) {} void setWidth(int newWidth) override { width = height = newWidth; } void setHeight(int newHeight) override { width = height = newHeight; } }; void mutation(Rectangle * r) { if(r != nullptr) { r->setWidth(r->getWidth() * 3); } } int main() { Rectangle r(5, 10); Square s(5); mutation(&r); mutation(&s); std::cout

  • @itachinight
    @itachinight3 жыл бұрын

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

  • @0imax

    @0imax

    3 жыл бұрын

    Да, надо было просто сделать в базовом классе метод resize(w, h) и поломать голову над тем, как его переопределить в потомке.

  • @Eugene.g
    @Eugene.g3 жыл бұрын

    от изменения Width извне меня аж покоробило )) я бы, конечно, на своих C# и TS, первым делом закрыл сеттер для Width, сделал бы для квадрата и прямоугольника какой-нибудь implements IChangableWidth с методом "public void ChangeWidth(int newWidth)", но проблему с конструктором это бы, конечно, не решило

  • @0imax

    @0imax

    3 жыл бұрын

    Я бы вообще не наследовал :) Но если прям позарез надо, то сделал бы автоматическое изменение ширины и высоты при изменении любого из них, а так же кидал бы исключение, если попросят квадрат, скажем, 5х15 :)

  • @Eugene.g

    @Eugene.g

    3 жыл бұрын

    @@0imax ну да, я это и описал, интерфейс вместо наследования. Только конструктор "new Rectangle(5,5)" и исключение выглядит уже костылем и нарушением LSP

  • @0imax

    @0imax

    3 жыл бұрын

    @@Eugene.g от нарушения тут в любом случае не уйти, если пытаться работать с квадратом и прямоугольником через общий интерфейс, использующий их размеры. Можно на сет любой стороны менять сразу и высоту, и ширину, но с точки зрения прямоугольника высота не должна зависеть от ширины, снова нарушение. Единственный, как мне кажется, адекватный вариант - сделать квадрат обëрткой над ректом, и использовать и рект, и квадрат через интерфейс, ничего не знающий об их размерах. Тогда нарушения не будет.

  • @DeathIncarante
    @DeathIncarante3 жыл бұрын

    Вопрос не совсем по теме - не эффективнее было бы ли создать метод Mutate у объектов? Пусть каждый тип фигуры сам определяет своё поведение при мутации.

  • @user-eo3ns2ub9l

    @user-eo3ns2ub9l

    3 жыл бұрын

    Или параллельную иерархию, где потомки будут переопределять метод Mutate() и делать с фигурой что хотят?

  • @VseNikiSukaZanyaty

    @VseNikiSukaZanyaty

    3 жыл бұрын

    Эффективнее и не будет нарушения инкапсуляции

  • @mik_zd

    @mik_zd

    3 жыл бұрын

    Квадрат это прямоугольник с ограничением соотношения сторон - ещё объект/класс. Изменение это ещё объект/класс который с учётом ограничения

  • @user-gl9yo8rz8k
    @user-gl9yo8rz8k3 жыл бұрын

    Шуточное объяснение принципа: Если что-то выглядит как утка, плавает как утка, крякает как утка, летает как утка, но требует батарейки - значит вы что-то делаете не так.

  • @Mike-hp3fh
    @Mike-hp3fh3 жыл бұрын

    Зачем использовать ООП, если с ним столько проблем?

  • @user-dn7qr7vs1h
    @user-dn7qr7vs1h3 жыл бұрын

    ООП тут вообще второстепенен, суть ведь про подтипирование. LSP к ООП применяется только вследствие того, что наследование является одним из вариантов подтипирования ( o)( o). Думаю, на этом было бы важно заострить внимание, т.к. понимание этого могло бы дать пользу не только адептам ООП, но ещё и тем, кто просто использует языки с подтипированием и возможностью создавать новые подтипы.

  • @i_dont_want_a_handle

    @i_dont_want_a_handle

    2 жыл бұрын

    был где-то очень годный доклад про канонические принципы SOLID, в частности про LSP, но я никак не могу ее найти... это был как будто Kevlin Henney, но может и не он, в общем да, там был как раз посыл про то, что LSP - это про подтипы, а не про ООП, со ссылками на оригинальную работу этой Барбары Лисков

  • @DonEstorsky
    @DonEstorsky3 жыл бұрын

    Так это прямоугольник является частным случаем квадрата, но с разными сторонами? ;)

  • @0imax

    @0imax

    3 жыл бұрын

    Скорее квадрат - это такое состояние прямоугольника, когда w == h :) Хуже, когда от объекта нужно _поведение_ квадрата, т.е. при изменении одной стороны менялась бы и вторая.

  • @DonEstorsky

    @DonEstorsky

    3 жыл бұрын

    @@0imax это мы привыкли так считать, что квадрат исключение или состояние прямоугольника, а может прямоугольник -- это искажение квадрата? С кругом мы считаем основной фигурой именно круг! Эллипсы же привыкли считать искажениями круга. Круг правильная фигура, а не частный случай эллипса. Всё зависит от восприятия.

  • @0imax

    @0imax

    3 жыл бұрын

    @@DonEstorsky Это да. Восприятие многое решает. Сравнить хотя бы парадигмы ООП и ФП :)

  • @miptkol
    @miptkol3 жыл бұрын

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

  • @S0ERDEVS

    @S0ERDEVS

    3 жыл бұрын

    Прочитай хотя бы Вики, что-ли: В последующей статье[2] Лисков кратко сформулировала свой принцип следующим образом: Пусть q(x) является свойством, верным относительно объектов x некоторого типа T. Тогда q(y) также должно быть верным для объектов y типа S, где S является подтипом типа T. Роберт С. Мартин определил[3] этот принцип так: Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.

  • @miptkol

    @miptkol

    2 жыл бұрын

    @@S0ERDEVS 1. Конструктор класса не является "свойством" экземпляра класса. Конструктор подтипа не обязан принимать те-же параметры, что и конструктор надтипа ни в одной из обозримых реальностей. Он обязан только создавать экземпляры подтипа при передаче !корректного! набора параметров. 2. В языках с богатым синтаксисом и метаданными, перечень допустимых для определённого метода исключительных ситуаций также является частью сигнатуры, а, значит, и интерфейса. Подтипы, действительно имеют право только сокращать этот перечень (не имеют права расширять). Но JS - не один из этих языков. Для любого действия может быть сформирована исключительная ситуация, которая может быть чем угодно. И это проблема пользователя, что он ее не обработал. 3. Если бы квадрат мог иметь стороны разного размера, то это уже был бы не квадрат (см. базовый курс планиметрии) - это тривиальная ошибка, связанная не спринципом Лисков, а с нарушением предметной области. 4. Использовать википедию вместо первоисточника - это признак высшей степени некомпетентности. (Тем более, что в ней даже ссылки на источник указаны) Википедия - средство ликбеза, а не источник истины.

  • @user-bq7co7fv2p
    @user-bq7co7fv2p3 жыл бұрын

    Проблема в том что ты говоришь что квадрат это частый случай прямоуголика у которого h = w а сам берешь, еденичный случай использования hw и делаешь их равными. Нужно было задать сетеры чтобы синкать w и h

  • @user-bq7co7fv2p

    @user-bq7co7fv2p

    3 жыл бұрын

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

  • @user-bq7co7fv2p

    @user-bq7co7fv2p

    3 жыл бұрын

    Мне кажется вывод неправильный. Наследовался можно. Нельзя использовать полиморфизм

  • @user-bq7co7fv2p

    @user-bq7co7fv2p

    3 жыл бұрын

    А можешь окнуть или сказать что я даун) что нибудь)

  • @user-dy4nj1cd2d
    @user-dy4nj1cd2d3 жыл бұрын

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

  • @0imax

    @0imax

    3 жыл бұрын

    Есть редкие случаи, когда это нарушение сделано осознанно для универсальности интерфейса, и это нарушение настолько очевидное, что сразу понятно, как делать НЕ надо :)

  • @Boortwint

    @Boortwint

    3 жыл бұрын

    Ну да. Тот же принцип единой ответственности можно смело нарушать, если изменение одной ответственности в классе не требует изменения другой ответственности. А попытки соблюдать этот принцип в одном классе порой нарушают его в другом. Да ещё и в добавок могут параллельно добавить проблем с принципом открытости/закрытости других классов.

  • @alexandr-v
    @alexandr-v3 жыл бұрын

    7:25 Не понял в чем тут ошибка. а сколько должно было получится, не 25? Сначала говоришь, мы хотим создавать прямоугольники, а потом создаешь квадрат, спрашивается, зачем? Только что же хотел только прямоугольники создавать.

  • @user-ey5xw2nx9s

    @user-ey5xw2nx9s

    3 жыл бұрын

    Так квадрат - наследник прямоугольника

  • @vavilov2212
    @vavilov22123 жыл бұрын

    Аффтар жжот!

  • @cyrilanisimov
    @cyrilanisimov3 жыл бұрын

    Если фарисеи дожили до наших дней, то они стали программистами. P.S. а если рассмотреть квадрат не как отдельный класс, а как частный случай прямоугольника с методом bool isSquare()? И конструктор перегрузить (int a, int b = -1) { if(b == -1) { b = a; isSquare = true; }} P.S.S. Сначала пишу комментарии, потом смотрю видео))

  • @CHERNOMORGAMES
    @CHERNOMORGAMES3 жыл бұрын

    Как-то сразу резануло, что квадрат наследует от прямоугольника. Интуитивно, чувствовалось, что что-то не так. Наверняка у многих такое же ощущение возникло. Действительно, если прямоугольник будет наследовать от квадрата - проблемы не возникнет. Квадрат "проще" или "абстрактнее" прямоугольника. Если куб будет наследовать от гиперкуба: мы сразу "почувствуем", что что-то не так - здесь то же самое.

  • @jokeer3148
    @jokeer31483 жыл бұрын

    Как будто современные тренды ютуба, только на реалии IT блогера.

  • @sergeydevyatov
    @sergeydevyatov3 жыл бұрын

    Суть проблемы не ясна. Если Square перестанет наследоваться от Rectangle, код справа не начнет работать как-то иначе, а помещать в builder конструктор Square останется возможным. Стало быть проблема в разработчике, который помещает в этот билдер квадрат и удивляется, что площадь неверно посчитана

  • @0imax

    @0imax

    3 жыл бұрын

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

  • @AndrewLewman

    @AndrewLewman

    3 жыл бұрын

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

  • @vovasokolov768
    @vovasokolov7683 жыл бұрын

    суть проста: не наследуйте классы и делов то!

  • @0imax

    @0imax

    3 жыл бұрын

    Суть проста: не используйте ООП, а лучше вообще не пишите код :)

  • @dann1kid
    @dann1kid3 жыл бұрын

    Шрифт с засечками трудноразличим на этом фоне

  • @nepBoHax
    @nepBoHax3 жыл бұрын

    Кому в голову придет создавать квадрат, когда уже есть прямоугольник. Незачем плодить лишнюю сущность, квадрат и прямоугольник это одно и то же, ну передай ты два параметра вместо одного, это так сложно ?

  • @user-uh8vk7fc9x
    @user-uh8vk7fc9x3 жыл бұрын

    А где собственно нарушение LSP? Конструктор же не является частью интерфейса.

  • @0imax

    @0imax

    3 жыл бұрын

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

  • @user-uh8vk7fc9x

    @user-uh8vk7fc9x

    3 жыл бұрын

    ​@@0imax суть в том, что видео называется "Нарушаем принцип подстановки Лисков и смотрим, что получилось", но никакого нарушения на видео нет. Есть мутирование объекта и есть плохой дизайн "билдера". Кстати, если у прямоугольника будет метод resize(width, height): Rectangle, то у квадрата этот метод может просто возвращать прямоугольник, если переданные стороны разные, и квадрат, если стороны равны - и это по прежнему не будет нарушением LSP.

  • @0imax

    @0imax

    3 жыл бұрын

    @@user-uh8vk7fc9x ну вот и начинаются финты ушами - вместо того, чтобы поменять две цифры, приходится создавать новый объект. Опять же, как быть с методами setWidth и setHeight ?? Если квадрат при изменении одной стороны будет менять и вторую, дабы остаться квадратом - может получиться ситуация, когда мы насоздавали прямоугольников, но один из них получился квадратом случайно, и далее на смену ширины реагирует не так, как мы ожидали. Если же квадрат при изменении одной из его сторон будет "превращаться" в прямоугольник ( как с предложенным выше ресайзом ), то вообще не понятно, нафига нужен класс Квадрат, если ведёт себя он точно так же, как его родитель :)

  • @S0ERDEVS

    @S0ERDEVS

    3 жыл бұрын

    @@user-uh8vk7fc9x попробуй сделать три интерфейса (в контексте условий видео) Shape, Rectangle, Square, тогда поймешь о чем речь в видео. Там не про реализацию конструктора, а именно про реализацию интерфейса через конструктор. Что касается примера про resize, то это нифига не "просто", так как позволяет обходить проверку типов. И тут надо долго и вдумчиво читать про инвариантность, ковариантность и контрвариантность. В двух словах не объясню.

  • @Mike-hp3fh

    @Mike-hp3fh

    3 жыл бұрын

    В этих примерах конструктор является частью интерфейса, т.к. в одну из функций передается класс.

  • @nanouasyn
    @nanouasyn3 жыл бұрын

    либо автор не понимает, что такое утиная типизация, либо в js всё настолько шиворот навыворот, что и утиной типизацией называется не то, что у всех. утиная типизация - это когда мы устанавливаем факт реализации интерфейса по факту наличия у объекта необходимых для реализации этого интерфейса методов. скажем, если мы считаем, что прямоугольник - это любой объект, реализующий метод area, и для того, чтобы понять, прямоугольник ли перед нами, узнаём, определяет ли данный объект метод area, то мы используем утиную типизацию. однако, если мы проверяем, является ли объект экземпляром класса Rectangle или его дочернего класса, то это уже обычная типизация.

  • @Alexander-lp2qy
    @Alexander-lp2qy3 жыл бұрын

    Выводы: Оставить только Rectangular. Не использовать наследование. Использовать классы как структуры данных, а логику запихнуть в функции.

  • @0imax

    @0imax

    3 жыл бұрын

    Достаточно ограничиться классом Rectangle. Выносить функции наружу нет смысла.

  • @dmproger
    @dmproger3 жыл бұрын

    гут. но хорош маяться, переходите на Ruby class RectangleOrSquare attr_accessor :width def initialize(width, height = nil) @width = width @height = height end def area width * height end def height @height || @width end def height=(value) @height = value if @height end end

  • @KopoLPedov

    @KopoLPedov

    3 жыл бұрын

    def width @width || @height end def height @height || @width end ооочень интересно, продолжайте(нет)

  • @dmproger

    @dmproger

    3 жыл бұрын

    @@KopoLPedov А продолжать и не нужно, все готово. width даж не требуется патчить (обновил), только height. И никакого аccidental complexity с бесконечными паттернами.

  • @PowWowVideo

    @PowWowVideo

    3 жыл бұрын

    @@dmproger добавь еше в название...OrCircleOrOval и поиграйся с двумя радиусами вместо или вместе с w и h.

  • @donpedro2125
    @donpedro2125Ай бұрын

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

Келесі