Проектируем чашку, человека и метод "пить"

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

КОМЕНТАРІ • 342

  • @DubinArtur
    @DubinArtur 3 роки тому +403

    Никогда ещё человек не пил так осознанно

  • @undefined-n5v
    @undefined-n5v 3 роки тому +169

    Отличное видео и подача. Очень хочется ещё подобных видео

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

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

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

      Согласен. Мне тоже не хватает такой информации.

  • @konstantinsemenov1627
    @konstantinsemenov1627 3 роки тому +110

    Предлагаю разнести человека и чашку в разные микросервисы =)

  • @DubinArtur
    @DubinArtur 3 роки тому +200

    Очень важна постановка задачи
    Сидит мужик, листает газету, видит объявление: Раскидать песок. 500₽
    Позвонил, заказчик:
    - Придёшь, раскидаешь песок, заплачу 500₽, договорились?
    Мужик согласился.
    Приходит, а там 3 камаза песка. Говорит заказчику:
    - Тут 3 камаза песка, подними оплату
    Заказчик ни в какую. "Мы договорились, слово держи"
    Мужик взял жменю песка, швырнул в сторону и говорит:
    - Давай оплату
    - ??
    - Мы не договаривались, что раскидаю весь песок

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

      надо было NDA подписывать

    • @roman-bolkhovitin
      @roman-bolkhovitin 3 роки тому +18

      "Рабинович с одной стороны и Одесское пароходство с другой..." (с) анекдот

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

      @@roman-bolkhovitin хD

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

      @Старший Санитар " - Если хоть кому-то расскажешь, что мы тут самосвалы с песком разгружаем на халяву - Мы быстро тебе жизнь подпортим. "

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

      @@dmtpp он пример тебе показывает, а ты язвишь, негодяй

  • @Cleannetcode
    @Cleannetcode 3 роки тому +79

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

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

      Дело в том, что любая задача которую нужно запрограммировать должна в конечном итоге совершать какие-либо I/O операции, иметь side-эффекты.
      Это должен быть вывод на экран, запись на диск и передача данных по сети, вывод звука.
      Задача должна быть сформулирована в этих терминах, иначе это это очередной фейк, и подмена понятий.
      Так происходит с каждым ООП-туториалом, потому что ООП, так получается, крайне скверно ложится на то чтобы задача была описана в терминах того что должен сделать компьютер, вот и приходится придумывать манявселенную с человек.пить и прочими мяукающими котами и гавкающими собаками.
      В реальности получаются Фабрики.СделатьАбстрактныйОбъект и Менеджеры.ЗапуститьПроцесс2

  • @borispr7824
    @borispr7824 3 роки тому +32

    Такой контент я давно искал. Но ютуб считает что в рекомендации лучше положить как 8 лет назад Камаз утонул

  • @СергейПанов-з3ц
    @СергейПанов-з3ц 3 роки тому +66

    Реализовывал бы эту задачу первым, самым быстрым и простым способом.
    Если бы появлялись новые требования, переписывал бы код, двигаясь к последнему способу по мере необходимости.
    Новые требования могут и не появиться, а мы сделаем 10 уровней абстракций, которые нам не понадобятся.

    • @scarlatum
      @scarlatum 3 роки тому +7

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

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

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

    • @konstantinkouptsov7513
      @konstantinkouptsov7513 3 роки тому +17

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

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

      @@konstantinkouptsov7513 как же жизненно

    • @themescaline9207
      @themescaline9207 2 роки тому +5

      Вот где становится явной важность корректности и полноты требований к задаче. При простой постановке задачи - есть Человек, который Пьет из Кружки, явно нужно использовать первый вариант. Просто другие варианты противоречат KISS и YAGNI.

  • @AlexQuidditch
    @AlexQuidditch 3 роки тому +34

    Хотели банан, а получили гориллу с бананом в джунглях.
    Реализация огонь 🔥

  • @np-wl7hf
    @np-wl7hf 3 роки тому +3

    Очень понятное обяснение не только про проектирование, но и про применение ратернов, очень классно!)

  • @НиколайТуршиев
    @НиколайТуршиев 3 роки тому +6

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

  • @kirillcherkasov3450
    @kirillcherkasov3450 3 роки тому +29

    Не хватает примера реализации кодом в итоге. Вроде понятно, но вдруг не так понял.

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

      Любой проект на java spring открой)

  • @stanislavsh6582
    @stanislavsh6582 3 роки тому +14

    Это конечно весело, но на деле усложнение системы.Все же помнят про KISS и бритву Оккама. Вот мы заложили эту возможность расширения системы, хорошо, а расширения - никогда не произошло, но кодовая база стала сложнее для понимания новым разработчика и они уже чтобы решить задачу по добавлению новой логики - тратят не 10 минут, а 2 часа, потому что в реальных проектах будет на DrinkController, а какая-нибудь монструозная фигня, с фасадами, прокидыванием событий, мостами, медиаторами, декораторами фабриками и прочим-прочим и чтобы добраться уже до самой логики - придется нехило постараться.
    В общем. На мой взгляд - второй вариант - неидеален, но он прост, он довольно расширяем, а главное он не прячет логику за отдельной сущностью. Опять же, тут пример довольно простой, но ведь взяв на вооружения подобные принципы - люди начинают все декомпозировать-декомпозировать, выделять сущности(вот вам выпивака, закусака и наливака, а вместе они образуют студента), выделять интерфейсы, в итоге куча каких-то кусков логики лежат в воздухе а как оно собственно работает - может понять только тот кто это написал(и то не факт), либо человек, которому не жаль было потратить неделю времени.

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

      Так фреймворки же берут на себя всю грязную работу, никто с нуля не пишет. Или вы пишете?

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

      @@S0ERDEVS В веб-разработке, скорее всего, никто с нуля не пишет, но есть множество других доменов. Например готовые фреймворки для автомобильной индустрии мне не известны. Однако там так же успешно используются и микро сервисы, и MVC, и дизайн паттерны.

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

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

  • @АндрейСкрипко-с7р
    @АндрейСкрипко-с7р 3 роки тому +4

    Классный разбор! Спасибо за труды) на самом деле на таких абстрактных, но близких к реальному миру, вещах интересно пробовать учиться проектировать. Такое упражнение для мозга)

  • @ДенисМалахов-к9э
    @ДенисМалахов-к9э 3 роки тому +40

    Конечно тут представлен простой пример, но мне кажется он отражает суть современной разработки. Можно гнаться сколь угодно за принципами и паттернами, но когда вы попадаете в среду, где предметная область для вас в новинку, а требования и сроки уже обозначены, вы будете проектировать архитектуру под текущие требования так, как вам кажется правильно. При этом вы еще n-ое количество раз будете пересматривать свои наработки. А когда вам покажется, что вы все контролируете, то появится требование, осознав которое, вы прошепчете у себя в голове: "*лядь, как я сразу это не учел?"

    • @ОлегМосягин-р8й
      @ОлегМосягин-р8й 3 роки тому +2

      Поэтому Роберт Мартин топит за TDD, чтобы можно было делать безболезненный рефакторинг.

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

      @@ОлегМосягин-р8й Как тесты, написанные для 1 варианта помогут сделать безболезненный рефакторинг в последний вариант? :) Да там процентов 90 тестов надо будет переписывать, и еще неизвестно сколько писать новых :)
      Тесты нужны при точечных доработках и расширении системы скорее, нежели при глобальном рефакторинге.

    • @ОлегМосягин-р8й
      @ОлегМосягин-р8й 3 роки тому +2

      @@dmitriyobidin6049 никак, если изменились интерфейсы и разделение на модули, то и тесты придется переписать. Но по крайней мере тесты провоцируют писать более мелкие и узкоспециализированные модули. Просто если у нас весь проект состоит не только из этих двух классов, а есть что-то еще, то тесты позволят убедиться, что остальный проект не сломается, пока мы переписываем эти два класса с тестами на них.

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

    Потрясающая🌞 подача материала 🌞
    Понятно даже мне

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

    Спасибо за видео! Прекрасный формат видео (рубрика)! Лайк

  • @bublik20
    @bublik20 3 роки тому +19

    Побольше таких нужно, спасибо!

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

    Каждое видео очень воодушевляет.
    Спасибо за ёмкое объяснение таких тонких (особенно для новичков) моментов! 😌

  • @viv81ster
    @viv81ster 3 роки тому +23

    Предлагаю объединить сущность сосуд и человек
    Человеко-сосуд
    Тогда человек может пить из другого человека хоть до бесконечности

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

      это уже система вампиризма

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

      Да! И тогда можно будет не только пить человеку, но и даже переливать из бутылки в чашку.

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

      ты про свою жену?

  • @КонстантинПотапов-я7м

    В начале видео говорится, что необходимо спроектировать ситуацию в ооп парадигме. На самом деле получилась анемичная модель, которую дергает контроллер. Мало того что паттерн mvc предполагает логику размещать в моделе, а не в контроллере, так ещё и нарушается один из главных принципов ооп дизайна - information expert. Контроллер управляет состоянием чашки и человека, вместо самих сущностей. Полученное решение напоминает паттерн transaction script

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

      нет, ты путаешь модель и сущность. Доменную модель с доменной логикой, контроллером, моделью данных. Модель может быть пакетом (слоем), в котором есть отдельные доменные модели и отдельные бизнес-правила. Контроллер уже предоставляет методы, формализующие пользовательские запросы, отделяя интерфейс (GUI) от реализации (данных и бизнес-правил). Есть и другой вариант MVVM, там без контроллера, каждой пользовательской страничке присуща некоторая бизнес-сущность.
      Вообще, модель данных как раз должна быть максимально простой (плоской), без поведения., обычно хранится в базе в виде таблиц. На ее основе уже можно создавать сущности (через интерфейс) с поведением, которые и будут реализовывать присущую только им логику. А в случае на видео, логика не относится к одной сущности, бизнес-действие должно поменять состояние сразу нескольких объектов. Поэтому его нельзя приписывать к этим сущностям.

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

    Спасибо! Очень интересно по содержанию. Очень круто по визуалу!

  • @4Funoff
    @4Funoff 2 роки тому

    Прекрасное видео!! 👍🏻 Благодарю!! Всё предельно понятно!! 😊

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

    You Ain’t Gonna Need It. Делать нужно то, что нужно, то что стоит в задаче, а то, чего в задаче нет, делать не нужно. А если когда-то заказчик что-то поменяет, то он заплатит за новую задачу. А нам опять нужно будет делать только то, что нужно, то что в задаче... Жду новое видео!

    • @ИванИванов-р1г4х
      @ИванИванов-р1г4х 3 роки тому +1

      И, однажды, на требование добавление нового сосуда, заказчик услышит сумму в 100500 человеко-часов и пошлет Вас и Ваш подход далеко-далеко

    • @АнимусАнанимус
      @АнимусАнанимус 3 роки тому +2

      @@ИванИванов-р1г4х на это есть другие приемы работы. Например "если общий код встречается 3 и более раза, то нужно обобщить и переиспользовать".
      Цифра 3 может меняться в зависимости от, но метод довольно полезный как средство сдерживания и оверинжиниринга, и повторения кода.

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

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

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

    Для полного разрыва шаблона после Лисков и SRP новичку следует изучить принцип KISS

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

    Чисто доступно и понятно. + за продолжение подобных видео.

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

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

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

      Так в итоге у него и получился процедурный стиль. Две структуры (human и cup) и функция (action). ООП тут и нет никакого

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

    Отличный материал, хотелось бы продолжения. Спасибо

  • @henson2k
    @henson2k 3 роки тому +11

    Видео точно отражает три стадии мучения программиста при получении новой задачи: 1) и так сойдет 2) а что если?... 3) господи, что ЭТО?!!!

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

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

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

    Первое видео про ООП, которое я нашел для себя очень интересным

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

    Хотелось бы увидеть пример реализации класса, представляющего процесс пития.

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

      @@dmtpp Чтобы делать сложные и масштабные вещи, необходимо досконально постичь азы. Чтобы написать Войну и Мир, нужно сначала изучить азбуку, освоить слова и составление предложений. Эти вещи показательны. Я решил бы вопрос почти так же, но без класса-посредника, реализующего процесс пития. Мне вот и интересно как он будет реализован, будет ли агрегатом или композитом человека, а может вообще будет унаследован от глобальной божественной сущности Бахуса?

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

      @@redserjogha класс может быть реализован как действие, где сначала читается состояние кружки и в соответствии с ним изменяется состояние человека. Это действие, опционально, так же может выбрасывать событие, что оно произвело процесс опорожнение кружки и наполнение жидкостью человека. В последствии, все кто слушали это событие, могут начать своё действие, например: проверка на то, что именно было выпито и вызов соответствующей реакции (ухудшение самочувствия или его улучшение, гипотермия/гипертермия, отравление/излечение, восстановление водного баланса или же дегидратация организма).

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

      @@IgorLynn вы не. Observer описали в своем примере?

    • @IgorLynn
      @IgorLynn 3 роки тому +7

      @@evgenasd8892 да, но он опционален. Суть в том что мы вводим третью сущность и она просто меняет состояние двух моделей.
      У меня когда-то была похожая проблема, где было 2 космических корабля и они могли друг друга атаковать и наносить урон. Дилемма была в том, что не понятно у кого должно быть право наносить урон; должен ли атакующий корабль содержать метод DealDamage() и отнимать прочность/щиты у корабля которого он атакует или корабль который получает урон, должен содержать метод ReceiveDamage() и решать какой урон ему может нанести атакующий его корабль? По факту же, ни у кого из них не должно быть такой привилегии и доверия.

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

      @@IgorLynn спасибо

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

    Второму видео точно лайк за продолжение первого, за оба.

  • @fourbytes1
    @fourbytes1 3 роки тому +24

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

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

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

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

      @@pin689 никто не понимает ООП, только думают, что понимают. И у каждого свой ООП

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

    Весьма поучительно, спасибо!

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

    Очень круто !
    Впринципе ничего сложного если правильно начинать с самого начала.
    Почаще нужны такие видео.
    Это приблизительно тоже самое как осваивание речи у малых детей.
    Звуки.
    Буквы.
    Слова.
    ...

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

    Вот это я ппозрел))
    Видео просто топ! Вот бы еще разобрать на примерах)

  • @undersun6301
    @undersun6301 10 місяців тому

    За такой подробный разбор спасибо. Правда, спасибо. Задача хоть и простая, но повзволяет сразу увидеть, как мыслит человек. Я бы первым своим решением-приближением сделал бы функцию типа human_drink_from_cup() нарочно без классов. Всё-таки задача стояла примитивная, а мы начали фантазировать, а что будет если...

  • @ЗелёныйБен
    @ЗелёныйБен 2 роки тому

    Super!😁😁😁😉
    А это нормально если мы сделаем следующую иерархию интерфесов для класса кружки:
    > INTERFACES
    СпособныйСодержатьЖидкостьИнтерфейс (из шланга воду льют нам прямо в рот, то есть воздушная среда, способная содержать жидкость)
    ^
    УглублениеИнтерфейс (жидкость в лужах)
    ^
    СосудИнтерфейс (классы: кружек, бутылок)
    < INTERFACES
    Таким образом:
    class UserActionControllerInterface
    {
    function drink(человекИнтерфейс, СпособныйСодержатьЖидкостьИнтерфейс);
    }
    Ок?

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

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

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

    Какое название контроллера посоветуете для 3го варианта реализации? humanVessalController с функцией drink()

  • @GenaTolstij
    @GenaTolstij 3 роки тому +35

    Тю, по факту ты пришел к 2xDTO да ActionHandler, можно даже прикрутить третью DTO, которая описывает саму жидкость и "переливать" её из одной ДТО в другую. Но! Ты правильно заметил в самом начале, что очень важно "можем ли мы изменять систему", потому что иногда такое вот усложнение просто нерационально и не имеет смысла, если ты точно уверен, что никаких векторов развития никуда и никогда не будет в обозримом будущем, а нужно просто сделать в лоб и забыть. Типичная проблема программистов - когда просят построить садовую тачку, мы, по привычке, закладываем в конструкцию возможность расширения для реализации полётов на ней в космос с табором цыган на борту.

  • @vitaliyp.3007
    @vitaliyp.3007 3 роки тому +32

    Так выходит, что human не человек, а кукла, который не может сам пить, а нужно, чтобы кто-то поил

    • @fj8017
      @fj8017 3 роки тому +22

      В некоторых книжках пишут, мол, ООП нужен ещё и для того, чтобы не абстрагироваться от реального мира и что обычному человеку легче мыслить в рамках ООП. Чем больше изучаю, тем больше понимаю, что это не так. ООП становится всё дальше от реальности.

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

      @UCYB1-bWEzfKGTBSt6a5YoHw а ведь реально, если посмотреть на весь процесс инициализации (рождения) нового экземпляра человека (разных классов / национальностей и тп, унаследованных об супер-классов вверх по иерархии), то инстинкты - это firmware запрограммированный в контроллере физобъекта (с помощью биодисков- генов), а обучение в процессе жизни - это натаскивание его нейронной сетки через звуковые, световые и прочие интерфейсы (рефлексы как драйверы соответствующих IO-девайсов у человека);
      языки общения тоже разные у разных групп людей (но все так или иначе компилируются в некий гуманоидный IL низкого уровня), шины (СМИ, племенные и родовые связи) и брокеры сообщений тоже имеются - и многие великие "менеджеры (ака манипуляторы)" давно эти фреймворки выучили :))
      весь "гософициоз" с его законами и документами очень уж филофоски напоминают xml

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

      ​@@fj8017 класс Human - это не человек, а некоторый "представитель" человека в нашей системе. И так получается, что представители не обязаны разделять свойств и отношений тех, кого представляют. Например, есть муж и жена, которые разводятся, а есть адвокаты - их представители в этом процессе. Маловероятно, что адвокаты тоже разводятся при этом. Или классический пример с наследованием квадрата от прямоугольника отражает тот же феномен.
      Поэтому я бы не стал утверждать, что объекты в ООП так уж далеки от реальности. Просто мы оперируем не самими объектами, а их поведением.

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

    Очень круто!!!
    Спасибо огромное за контент)

  • @АлексейТитов-д9э
    @АлексейТитов-д9э 3 роки тому +6

    Отличный пример как программист вместо решения задачи сразу пишет свой фреймворк. Если не известны вектора развития компонентов этого решения то и усложнять не надо. На третьем добавлении схожего функционала сразу обозначится вектор, и надо будет только его учесть. В итоге меньше кода, и он будет отражать предметную область, а не непонятные фантазии программистов (замечу, программистов много, а проект один, а значит проще понимание кода проекта). А также проще отрефакторить код одного экрана, чем 10 файлов. P.S. Кстати, в третьем решении вся сложность будем в этом контроллере, где придётся обрабатывать, что лошадь не пьёт из стакана, а только из ведра, попахивает кучей if-ов, или ещё одним паттерном на 10 файлов.

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

      То есть надо всё переписывать, когда станет известно. Ну ок..

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

      1. Давно уже придумали фреймворки. Там все что нужно для 3-го варианта реализовано, генераторы кода есть и прочие "плюшки".
      2. Вы про полиморфизм слышали? Например, ad-hoc полиморфизм без всяких if-ов вызовет вам нужную реализацию, если же про языки с утиной типизацией и поддержкой мультипарадигм, то там есть замечательные декларативные подходы вместо if/switch, которые используют функции первого порядка. Да и контроллер может существовать не в одном варианте, если речь про модульный подход, то можно конфигурировать модуль, использовать DI и т.д. Короче нет там никаких "кучи if-ов". Было бы желание думать, а не решений полно.

    • @АлексейТитов-д9э
      @АлексейТитов-д9э 3 роки тому +3

      @@crutchmaster9637 лично мне проще переписать 10 строк кода, а не 10 файлов. А Вам?

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

      @@АлексейТитов-д9э Строк кода минимум на тысячу надо умножить и подумать еще раз.

    • @АлексейТитов-д9э
      @АлексейТитов-д9э 3 роки тому +3

      @@S0ERDEVS Вы комментируете 3-е решение в абстрактном вакууме, а не в реальном проекте, где что-то меняется, в задаче изначально неправильный акцент выставлен, что-то неизвестно на момент первых итераций, когда программисты уходят и болеют, ищутся баги по куче файлов, человек пытается уложить в голову логику. Это решение вообще это всё игнорирует. Понятно, что где-то такой подход реально отлично ложится и спасает от проблем в будущем, но не в случае рядовой задачи "попить воды".
      Примеры уж тогда надо подбирать более корректней, чтобы не было иллюзий, что там где есть решение в одну строку, надо генерировать кучу новых файлов и новых абстракций

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

    Очень полезное видео! Много в чем разобрался.

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

    5:30 Хорошее объяснение интерфейса..,.... 5+!

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

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

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

    Супервидос, спасибо

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

    Первый видос который досмотрел до конца. Оооч интересный формат :)

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

    Интересно!!

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

    Очень полезное видео! Спасибо за информацию.

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

    Сущность Существо. Сущность Емкость. Сущность Жидкость. Все наследуется от этих глобальных классов. человек корова, бутылка чашка корыто. вода чай ром. Это первое что пришло мне в голову.. Больше такого материала! Очень круто!

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

    Круто! Спасибо за видео. Буду использовать

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

    Спасибо 🙌🔝

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

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

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

      @@ДмитрийМязин-л5ш при этом самые кринжевые варианты - это как раз таки хотелки заказчика. Например, чтение pdf ж***й и выдача анализа этого pdf ртом...

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

      Интересует вариант выпивания чашкой человека

  • @zxw
    @zxw 3 роки тому +7

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

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

    Очень правильно все изложено, но не согласен с аналогией с MVC. MVC - это все-таки другое (ну контроллер точно в данном случае должен быть заменен на бизнес логику), а тут чистая 3-ех слойная архитектура - UI, бизнес логика (BL), и data access layer (DAL)

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

    3:00 Не совсем понятно, а почему нарушается LSP если мы даже не видим реализации? Вдруг код написан так, что замена Cup > Bottle и наоборот ничего не поломает в коде, а значит LSP нарушен не будет?

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

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

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

    Спасибо за видео, классный ролик

  • @oleksandr-petrovych
    @oleksandr-petrovych 3 роки тому +1

    Создаем новые классы желудок, печень, почка (одна), горло, рот, рука (одна), пиписька опционально - попа. Через агрегацию внедряем в человека. Никакого наследования. Потом, по цепочке (забыл паттерн) передаем чашку (сосуд) и человека в каждый класс. Ранее названные органы изменяют состояние человека и чашки.

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

    Спасибо, очень интересно было посмотреть

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

    что-то про MVC Остапа понесло). Это просто две модели, взаимодействующие между собой через интерфейс

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

    Спасибо, было интересно! Не хватило только визуализации в виде кода.

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

    Дядя Боб? Вы здорово выглядите)

  • @ievgenk.8991
    @ievgenk.8991 3 роки тому +10

    Забавно смотреть как java-ООП продается программистам как универсальное средство в котором можно мешать котлеты и мухи, а потом эти же программисты всеми правдами и неправдами пытаются отделить котлеты от мух, но на уровне архитектуры :)

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

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

  • @МаксимНазаров-э7ю
    @МаксимНазаров-э7ю 3 роки тому

    Браво, шикарно рассказал

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

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

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

      Любым случайным сеттером можем сломать доменную логику.

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

      >Проблема третьего варианта в том, что там нет ООП.
      Не вижу в этом никакой проблемы.

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

      Здесь нет бизнес-логики, поэтому о какой "анемичной модели" может идти речь? У нас есть транзакция и DTO-ка которая служит для переноса данных. При появлении бизнес-логики (и об этом было сказано в видео) она попадает в человека.
      Попробуйте сделать "не анемичную" модель с имеющимися данными, тогда вылезет много вопросов.

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

      ​@@S0ERDEVS Спасибо за ответ. Если инварианты будут обеспечиваться на уровне entity, например при отрицательном количестве жидкости в чашке будет вылетать исключение, а класс Drink будет передавать его в представление то это допустимый вариант.

  • @placeholder-g9g
    @placeholder-g9g 3 роки тому +5

    Осталось сделать последний шаг - избавиться от состояний. Т.е. заменить "action" на функцию и заменить интерфейсы алгебраическими типами. И вот уже нормальная функциональная модель, без всяких костылей.
    Кстати, в первом примере полиморфизм тоже есть - ad-hoc polymorphism.

    • @АнимусАнанимус
      @АнимусАнанимус 3 роки тому

      Чем ближе к совершенству, тем ближе к функциональщине (или к математике) :D

    • @РусланСитников-у4м
      @РусланСитников-у4м 3 роки тому

      Вы предлагаете мыслить как компьютер?

    • @АнимусАнанимус
      @АнимусАнанимус 3 роки тому

      @@РусланСитников-у4м ровно наоборот :)
      "мыслить как компьютер" - мыслить императивно, моделируя Машину Тьюринга в голове (операциональная семантика), описывая последовательность инструкций.
      А в математике наоборот, торжество декларативности (денотационная семантика). В математике (и функциональщине) мы обычно не расписываем последовательность инструкций для получения чего-то, а описываем свойства этого чего-то.

    • @РусланСитников-у4м
      @РусланСитников-у4м 3 роки тому

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

    • @placeholder-g9g
      @placeholder-g9g 3 роки тому

      ​@@РусланСитников-у4м Нет. Последовательность никак не противоречит декларативному подходу. Очевидно, что некоммутативные операции зависят от порядка выполнения, при любом подходе. Императивный подход это не про последовательность. Это про то, что операции могут изменять внешнее, по отношению к функции, состояние, в то время как функции зависят только их аргументов.

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

    Хотелось бы увидеть решение этой задачи в стиле Типажей и Структур как в Rust. Будет ли это проще?

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

      Первое что приходит на ум - это структура человек для которой реализован типаж Drink. Есть тип сумма(enum) Vessel, которая содержит все возможные сосуды.

  • @ЮрийХмелевских-ш8ч

    Классное видео, спасибо)

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

    Понравилось видео, MVC подходом реализации задачи впечатлён.

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

    Прикольно, спасибо!

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

    А действие даже не "пить", а скорее "перелить" из IVessel в IVessel. Тогда можно будет и из чайника в чашку перелить, а потом уже в человека

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

      Тип жидкости не влияет на сосуд, а на человека влияет ) А что бы влиять на сосуд, тут уже появляется вид жидкости - например кислота, расплавленный металл, лава. Крч мне кажется тут уже зависит от уровня абстракции и решаемой задачи.

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

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

  • @ЕгорЛазука-й1э
    @ЕгорЛазука-й1э 3 роки тому

    Круто, спасибо

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

    Спасибо за видео. Пора уже на патреон подписываться. Контент очень качественный.
    Жень, а смотри какая штука получается с этим mvc. Вроде все у нас объектно-ориентированное и по всем Solid и прочее. Но это все красиво работает когда состояние объекта в памяти долго висит. Чаще же нижний слой с состоянием уже хранится в сторедже каком то. И тут как возникает тема, что фактически у нас остаётся только метод перегонки из одного состояния в другое. И почему бы не взять для этого функциональный язык или какой то более функциональный подход.
    Вот все больше всяких апи и микро сервисов пишется, которые просто данные перегоняют, и по факту мы просто функцию оборачиваем в класс, в котором нам больше ничего не надо. И внимание вопрос, зачем тогда вообще класс и ООП в таких проектах

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

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

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

      Все эти парадигмы: процедурная, функциональная, ООП, etc. созданы для борьбы (преодоления) со сложност(ью/и). Философски, существует два подхода к представлению мира: атрибутивный и функциональный. Представляют вселенную в виде супер-пупер-гипертекста атрибутивисты, а функционалисты в виде взаимодействующих потоков энергии-вещества. ООП использует оба подхода, функциональный - методами, атрибутивный - полями, и борется со сложностью инкапсуляцией и абстрагированием. Это самая компромиссная и простая для понимания парадигма, оттого она и столь жизнеспособна.

    • @ievgenk.8991
      @ievgenk.8991 3 роки тому +1

      @@mikhailkh8560 ФП подход помогает хорошо структуировать код - чистые функции это уже очень хорошо фаргментированая сущность с очень прозрачной и предсказуемой природотой. И на выходе получается приложение где первыми идут данные а потом операции над ними, которые легко композируются и тестируются, "грязные" области тоже будут, но они будут более локализированы, что только плюс в контексте структурировании программы.
      А по поводу функций обёрнутых в функции... тут ничего сложного нет, вы же наверно заворачиваете объекты внутри объекты и умеете работать и понимать такой код - вот так же с функциями, только по проще :)

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

      @@ievgenk.8991 В теории я с вами абсолютно согласен. А вот на практике ни разу ничего хорошего не видел. Наверное я просто не везучий.
      А есть на условном гитхабе проект написанный подобным образом, при этом читаемый, расширяемый, легко, дебажащийся и живой?

  • @AlexeyG.
    @AlexeyG. 3 роки тому

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

  • @Code.bless_you
    @Code.bless_you 3 роки тому

    soer, ты Большой Человек)

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

    Если не сформулирована чётко цель, то такое нельзя надёжно спроектировать, потому что нельзя определить уровень абстракции

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

    Поговорка "Моешь чашку - думай о чашке" зазвучала по-новому))

  • @СтороннийНаблюдатель-ч6ф

    Молодец, грамотно. Думал будешь drink прикручивать к человеку, а потом к чашке попадая в классическую ловушку ООП.

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

      что за классическая ловушка?

    • @СтороннийНаблюдатель-ч6ф
      @СтороннийНаблюдатель-ч6ф 3 роки тому

      @@alexjuly7097 когда создают иерархическую систему, что бы объединить два необьединямых множества.

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

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

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

    Уважаемый S0ER, есть вопрос. Не совсем понятны в вашем варианте интерфейсы человека и ёмкости. Насколько я понял, предполагается, что у человека есть метод наподобие Drink(liquidType, volume), а у ёмкости метод получения её содержимого? Или команда (а насколько я понимаю, здесь использован именно этот шаблон) Drink просто в лобовую меняет состояние человека через get/set? Но тогда человек получается какой-то весьма анемичной моделью данных, которая уже ничего не инкапсулирует. Так же непонятно, как решается проблема "раздувания" модели человека - ведь каждая новая команда может влиять на совершенно разные детали состояния человека, и их число также будет расти. Насколько я понимаю, если заказчик хочет интенсивно расширять модель влияний на человека, то что-то всё равно будет раздуваться. В таком случае, возможно, ситуацию бы несколько упростил паттерн Состояние, только в модели человека был бы не один экземпляр состояния, а несколько (по количеству интересующих нас, как разработчиков, органов). Т.е. у каждого органа - своя сущность, а модель человека стала бы агрегатом в терминах DDD.

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

    Вагон лайков отправлен на разгрузку: 🖤🖤🖤🖤🖤🖤🖤🖤🖤🖤

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

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

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

      PourDrinkIntoHuman :)

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

      @@ДмитрийМязин-л5ш так как назвать то?

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

      @@gennady8263 название класса должно быть существительным

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

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

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

      @@ДмитрийМязин-л5ш забавно, мы вернулись к самому первому решению, только слово Human заменили на HumanController :)

  • @МихаилГагин-л5с
    @МихаилГагин-л5с 2 роки тому

    хорошее объяснение, работать будет. только вот весь этот паттерн, происходит из ущербности принципов построения С++ классов. Объект дринк - фактически состояний не имеет. Человек и чашка сводятся к набору интерфейсов суть которые геттеры и сеттеры. В альтернативной реальности Лиспа, есть CLOS, который изначально говорит что классы сводятся к геттерам и сеттерам, а вместо виртуальных классов действий, существуют обобщенные методы, не принадлежащие к классам. Создав одну обобщенную функцию вы можете добавлять туда взаимодействия произвольного кличества типов объектов. Т.е CLOS позволяет избежать создания трех не нужных сущностей действия и 2х интерфейсов. т.е сам этот паттерн уже заложен в CLOS.

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

    Подскажите, что используется для рисования на фоне какого-то контента на экране

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

      @@patrickowens7665 я спрашивал, что использует именно автор в своих роликах.
      А не твое мнение идиота.

  • @ФагимСадыков-ъ6с

    Комментарии как всегда выявляют довольно плотную группу людей которые хотят совершать ошибки под лозунгом "делаем в лоб, чтобы быстро дать заказчику ценность. И потом даже не учиться на них под лозунгом из серии "нельзя было предусмотреть, заказчик внёс несовместимые требования". Это вместо того чтобы понять что проблема в тебе как разработчике. Автор же ролика не говорит что он построил идеальную систему про кружки. Он пытается донести как на практике использовать понятие вектор развития и управлять энтропией которая при этом порождается. А комментаторы *от сохи" концентрируются на каких то не важных деталях.

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

    В MVC паттерне бизнес логика представляется в модели. Почему на диаграмме бизнес логика находится к контроллере? 16:37

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

      А что в твоем понимании бизнес логика в этой задаче?

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

      @@S0ERDEVS Я задал вопрос исходя из того, что вы представили на диаграмме, а не исходя из своего понимания. Я пытаюсь понять, что вы имели в виду. Или я не правильно понимаю картинку, и Action-Drink находится не в слое бизнес логики?

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

      @Seb Ler ты неправильно понимаешь картинку и Action-Drink это не бизнес-логика.

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

      @@S0ERDEVS Объясните пожалуйста картинку. Я думал, что на ней изображены снизу вверх три слоя:
      1. Слой данных
      2. Слой обработки данных (т.е. бизнес логика)
      3. Слой представления данных
      Которые в свою очередь соответствуют:
      1. Model
      2. Controller
      3. View
      из MVC паттерна

    • @АнимусАнанимус
      @АнимусАнанимус 3 роки тому

      @@S0ERDEVS, а бизнес-логика в этой задаче вообще есть? Где она?

  • @ИванНикитин-ч7б
    @ИванНикитин-ч7б 3 роки тому +1

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

  • @xrollup
    @xrollup 10 місяців тому

    Интерфейс не наследуется, он реализуется.

  • @ievgenk.8991
    @ievgenk.8991 3 роки тому +6

    Как насчёт создать базовый класс Сосуд и создать класс Человек который наследуется от Сосуда, ведь человек в этой задачи ничто иное как сосуд! И стакан сосуд, а жидкость это данные которые перетекают из одного сосуда в другой. Вот она красота истинного ООП!

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

    А второй способ позволит реализовать изменение стейтов обоих объектов в транзакции? 🧐

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

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

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

    Круто.👍

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

    Кабздец. Как было хорошо во времена qbasic and turbo pascal.

    • @АдисХоджаяров
      @АдисХоджаяров 3 роки тому

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

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

      спасибо за совет, но в нем я ненуждаюсь

  • @a.osethkin55
    @a.osethkin55 3 роки тому

    Спасибо

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

    3 вариант похож на то как это принято в Golang.
    Есть 2 интерфейса и функция обеспечивающая их взаимодействие. Ошибки пробрасываются наружу для обработки.

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

      Это наверное ещё один намек что это не ООП дизайн)

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

    А почему чашка - "cap", а не "cup"?

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

      1:21 - правый нижний угол ;)

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

    Спасибо! за разбор. Но жаль, что нет UML-диаграмм.

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

    человек- обьект, чашка - обьект, а действие это простая функция ,или класс в котором методы это действия?