№45 Разбор лекции Егора Бугаенко о настоящем ООП | Организованное программирование

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

раньше видео называется Взлёты и падение ОП это лекция в Новосибирске а Егор подозреваю что ты будешь это тоже смотреть в общем поехали посмотрим что из этого получится ребята обязательно оставляйте свои комментарии на эту тему если формат покажется удачным я буду его регулярно продолжать в том числе по тем видео которые вы мне будете присылать а что ж давайте попробуем посмотрим как это будет работать у меня есть три вещественных доказательства моей причастности к этой теме первое порядка 8ми лет назад написал книгу двухтомник Elegant Objects посвящённую как раз объектноориентированному программизму это практический набор практических рекомендаций программистам программистам на основных объекториентированных языках оказался этот двухтомник востребован материал оказался полезным для программистов и он уже несколько лет занимает первое место на полке OP на ГУР - это американский сайт международный сайт где обмениваются мнением читатели в том числе технической литературы второе - это framework TX который я вместе с коллегами создал порядка 6-7 лет назад он написан на Джаве с учётом тех принципов которые изложены в этом двухтом то есть с принципами то есть принципов как мне кажется чистого объектно ориентированного программа и последняя последние наверное года четыре активно являюсь соавтором соразработчиком э языка программирования Geлан который постулирует и пытается ээ показать некие новые подходы как нам кажется правильные подходы объектно ориентированного программирования мы о нём тоже сегодня немного поговорим какова структура доклада сначала мы поговорим первой части так условно доклад разделил я на всей части сначала поговорим о том какой прекрасный мир объектов существует объектно ориентированного на программе затем посмотрим как тяжело объектам в этом мире жить как не всё так прекрасно как нам хотелось бы ну и в конце расскажу о том как мы пытаемся помочь объектам и как у нас к сожалению не получается но всегда получается это сделать в идеале конечно для меня целью этого доклада было бы пробудить вас интерес к этой тематике и возможно кто-то из вас захочет стать соучастником соавтором наших исследований и помочь нам решить ту проблему о которой я вам сегодня расскажу в докладе я дам постановку проблем я не покажу вам как мы её решаем потому что её пока решить не мы никто никто в мире решить не может может быть кому-то из вас станет интересно и вы к нам присоединитесь короткое предупреждение перед началом некоторые вещи которые я вам скажу сегодня вам могут не понравиться особенно если вы программист особенно если программист на одном из основных языков программирования вы возможно с чем-то будете не согласны я вас призываю продержаться до конца лекции до секции вопросов и ответов не преровать не тормозить потому что вы скорее всего будете не согласны если мы будем прерываться то получится тяжело но будьте готовы к тому что несогласие будет и оно должно быть воспринято нормально итак сначала немножко истории наверняка вы её знаете тем не менее я поставлюсь три основных языка программирования которые как я понимаю определили что такое объектноориентированное программирование первый - это язык симула который был создан приблизительно в 1965 году э для симуляции процессов реального мира для Монтекарло анализа - это такой метод симуляции метод предсказания того что может получиться в результате наступления определённых событий был придуман язык и оказалось этим автором показалось что можно из этого симуляционного эксперимента сделать нечто большее сделать язык программирования тогда это было воспринято не очень дружелюбно не очень э не очень много энтузиазма вызвало у у коллег и этот язык так и остался в общем-то языком таким больше теоретическим тем не менее это был первый объектно ориентированный язык в котором было предложено понятие объекта класса под класса виртуальных методов это те принципы те те инструменты которыми мы работаем сегодня 10 лет спустя был предложен второй язык программирования который для нас важен язык Small Talk 10 лет прошло придумали язык Small Talk в котором авторы пошли дальше в сторону ещё большего объектноориентированного подхода и э дали миру постулат всё объект и цифра объект и буква объект и цикл - это объект и команда - это объект всё давайте сделаем язык в котором будет абсолютно всё объект и ничего кроме объекта появился small топ он был тоже экспериментальным и был создан в основном для как я я тогда на нём не программировал но как пишут это был язык в основном для обучения для того чтобы показать в том числе студентам как можно элегантно красиво в неком таком идеальном мире программировать однако чуть позже увидим что были серьёзные проблемы у этого языка в основном со скоростью выполнения программ и он так и остался в основном в форме такого языка больше теоретического чем практического хотя были конечно и решения на нём которые работали но это было интересный эксперимент прошло ещё 10 лет мы получили C++ c++ был предложен в восемьдесят пятом году бьёрн Страуструк наверняка вы знаете кто это был сделан язык C++ который у нас во многом синтаксис языка симла и добавил туда эффективность и скорость выполнения языка си и наконец-то объектноориентированное программирование получило доступ к реальным программистам мы наконец-то стали иметь возможность получили возможность писать на практическом ООП и у нас эти программы заработали и заработали относительно быстро и вот тут и открылась э открылась возможность для появления многих других языков после C++ стали появляться и и многие других десят языков вы сами их знаете мы на них программируем и Java в том числе и Python и Ruby и все остальные языки вот такая вот короткая история о а теперь об объектах как прекрасен мир объектов какой он должен быть в понимании создателей ООП в том виде в каком они это задумывали объекты - это абстракции я вам сейчас покажу что имеется в виду я буду показывать в течение всей лекции буду иногда приводить цитаты со ссылками на научные или полунаучные технические книги я это делаю с целью э добавления веса моим аргументам потому что многие вещи могут звучать не всегда увидите тем не менее я стараюсь опираться на работы тех кто был до меня посмотрим на эту диаграмму мы помним что объекты изначально были созданы для симуляции событий реального мира симуляции что-то происходит в реальном мире студент сидит в аудитории это событие реального мира мы внутри нашей программы пытаемся симулировать что же будет дальше если этот студент станет и будет например оказалось что можно моделировать события реального мира не только симулировать чтобы увидеть будущее но и в текущем моменте контактировать с объектами реального мира внутри компьютерной программы на диаграмме есть объекты двух типов вверху мы видим объекты реального мира и в статье так и называется: светофор э кресло самолёт это те объекты которые вокруг нас это могут быть в том числе объекты мира э компьютеров внутри внутри компьютера но за границами программы объекты которые существуют вне программы они вверху на диаграмме а в нижней части диаграммы объекты которые мы создали внутри нашего Java клуба каждый объект условно написанный на Джаве который синий является представителем прокси или абстракции объекта реального мира в реальном мире у нас есть студент который слушает лекцию внутри компьютерной программы у нас есть объект student у которого есть методы атрибуты и какое-то поведение и вот этот вот этот мапинг это соответствие между объектами программ и объектами реального мира и есть задача программиста построить этот построить эту корреляцию сделать так чтобы удобно было программировать удобно было работать с объектами внизу которые в свою очередь будут отправлять свои команды своё свои инструкции к объектам реального смотрите что объектов внизу не такое количество как вверху и не всегда один к одному времени некоторые объекты внизу работают с двумя объектами вверху один объект Student может вполне себе обращаться в несколько объектов реального мира например в базу данных например в файл одновременно ещё и в мобильный телефон например студент мы имеем один стudent в Java мы к этому студенту обращаемся и даём какую-нибуд команду а он отправляет три команды в объекте

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

слоя которую мы просто используем в своей жизни что вот этот объект ну это немножко официально конечно звучит и странно но в принципе когда мы с кем-то о чём-то рассуждаем мы можем использовать этот термин и в этом смысле моделированием таким мы занимались всегда я уверен что это и сотни лет назад в общем-то всю жизнь было когда мы рассматривали какую-то систему как она работает как там взаимодействуют элементы а при этом сейчас Егор когда вот это про всё это говорит что вот тут удобно тут неудобно это чуть больше техническая часть чем часть относящаяся к непосредственно к ООП а ООП просто приписывают ну это так же как и многим другим вещам приписывает много вещей которые к нему не имеют отношения то есть здесь мне кажется сработало просто совпадение на наименования то есть типа люди понимают что такой объект как концепция то есть если я подойду сейчас там не знаю к своим детям задам им этот вопрос они смогут объяснить что такое объект в принципе потому что это понятие которое мы используем в реальной жизни из-за того что объектноориентированное программирование захватило это слово для обозначения своих концепций а создалось неправильное впечатление что если у меня нет объектного ориентированного программирования значит у меня нет объектов нет понятий я часто с этим сталкивался когда ты а разговариваешь с людьми и например объясняешь как можно в ирланге писать как можно в кложе писать как можно в других языках писать и они говорят что ну а как вообще вы это делаете у вас же там нету объектов так вот давайте по порядку значит это первое что вообще касается объектов второе а здесь Егор начал говорить про императивное программирование как бы говоря о том что вот есть объектно ориентированное программирование а есть вот значит императивное приводит пример Паскаль говорит про процедурное я подозреваю что он либо упрощает либо ну специально какие-то детали ну опускает какие-то детали либо просто как это часто бывает я потому что тоже много говорю где-то выступают иногда говоришь какие-то слова которые ну в данном контексте не совсем правильные но они вот льются и тебе нужно продолжать речь да даже сейчас я говорю я понимаю что у меня иногда рот быстрее что-то делает чем мозг успевает это обработать так вот дело в том что объектноориентирное программирование и императивное программирование нельзя ставить как бы на один ряд это вообще-то не совсем связанные вещи то есть есть императивная например и функциональное императивное связано с тем что у нас есть изменяемое состояние нет рефре а рефренциальной прозрачности и это означает что внутри программы много изменяемого состояния и в этом смысле объектноориентирное программирование то которое обычно реализовано во всех языках является максимально императивным программированием и при этом это не означает что оно не может быть а другим например функциональным опять же но на практике это встречается крайне редко и если встречается то в каком-то ограниченном режиме классический пример - это цепочки обработки коллекции когда мы делаем мафиит идя у нас на выходе генерируется каждый раз новая коллекция и мы не делаем изменений как правило это считается злом или вообще даже запрещено языком и таким образом получается что синтаксис с точки зрения того как мы привыкли мы можем назвать объектным потому что мы через точку это вызываем но по факту а это является функциональным программированием то есть для функционального программирования или императивного программирования вообще не имеет значения какими сущностями вы оперируете внутри как вы их называете как они выглядят объединяются там методы и функции в одних концепциях которые называются классами или вообще слова классы у вас нет императивность и функциональность от этого не зависит соответственно объектное программирование и есть а в большинстве случаев именно императивное программирование а это второй момент третий момент который я здесь услышал а а про пример процедурным программированием и Паскалем тут важно понимать что в те времена когда появились большинство этих языков и они утверждали какие-то определённые вещи а в целом развитие языков было на достаточно низком уровне и э господство например процедурная парадигма а процедурная тоже часть императивного программирования между прочим что это значит это значит что в процедурном мире в первую очередь состояние всегда было глобальным то есть у нас на во всей программе существовали какие-то данные которые могли использоваться всеми частями программы и процедура как концепция сейчас часто процедуру слово процедура используют ну не совсем в правильном варианте но если мы берём процедурное программирование процедуру как концепцию то процедура - это не функция то есть она не возвращает значений это штука которая занимается исключительно изменением состояния а или выполняет какой-то побочный эффект соответственно получается что в такой парадигме программирование действительно было ну мягко говоря ужасом то есть на маленьких объёмах программ это ещё как-то могло работать и с этим можно было жить но если размер программы увеличивался это превращалось в кошмар потому что просто представьте у вас есть одно большое глобальное состояние и огромное количество кода которое просто это состояние в любой момент каким-то образом меняет ну и все проблемы которые из этого следуют поэтому во многом то что привязали к объектноориентированному программированию когда оно появилось а ну конечно не всё то есть там нюансов много а связано с тем что а такие языки дали модульность которая реализуется и без объектов просто это связали из-за того что это появилось ну вот в этих языках а и они в том числе стали использовать активнее функции хотя функции были в Лиспах и до этого и в общем-то всегда это существовало и более того это ещё и в математике да существовало то есть это гораздо ближе функциональная парадигма в этом плане к более историческим так сказать древним вещам которые в общем-то в математике ещё изначально появились в общем смысл в том что противопоставлять ОО с функциями даже не парадигме а именно процедурному программированию это не совсем правильно это такое лукавство получается то есть может быть оно не осознанное чаще всего но оно фактически сравнивает с языками предыдущих поколений предыдущих уровней которые работают ну так как вообще в принципе писать нельзя потому что если мы сейчас будем сравнивать например с современными языками мм это например Кложа это тот же самый эликсир акамол и так далее то вы увидите очень простую вещь везде абсолютно прекрасная модульность изоляция в большинстве этих языков процедуры не используются и изменяемого состояния там не так уж и много а при этом там есть все те же самые понятия там есть все те же самые вещи о которых сейчас в том числе будет говориться то есть в этом смысле это сравнение оно уходит корнями вот в такую глубокую древность и транслируется до сих пор хотя на самом деле в современных языках а вот этих вот недостатков нету а по поводу того что м это выглядит более нативно или ненативно но на самом деле это уже не так и а мы об этом сейчас тоже поговорим просто давайте послушать дальше а потому что там будет ещё несколько интересных моментов которые надо будет остановиться обсудить и это нас отличает от императивного программе две технические ээ техники две технические два технических инструмента дают нам возможность эту абстракцию внутри программы обеспечить первое динамические дис то есть динамический динамическая диспечеризация или польз связывание работает это следующим образом представьте что у вас есть метод слева Java метод или какой-то язык программирования кук который получает фрукт и дальше у этого фрукта спрашивает: "Сколько же у тебя калорий?" Когда мы обращаемся к фрукту и спрашиваем количество калорий реальный запрос уходит либо в сторону яблока либо в сторону сли и они уже нам отвечают: "Колько вы калории" как именно реализован функционал метода калории calories зависит от конкретной имплементации это связывание происходит в конце когда программа уже выполняется когда мы пишем программу то метод куп не знает что у него будет в руках то ли к нему придёт яблоко то ли к нему придёт слива он полагается лишь на обещание этого объекта реализовать метод с но совершенно не хочет знать о том какая будет реализация и это важная фишка без которой абстракция была бы не Но поскольку эта фишка есть то мы имеем возможность представить себе студента не зная например какой это конкретно студент и с какой он группы нас просто интересует его например успеваемость мы спрашиваем получаем ответ: "А как там?" Ох здесь Егор я думаю прекрасно сам знает что он тоже очень сильно упростил потому что студенты разных группы - это не разные типы объектов и соответственно динамическая диспечеризация здесь не имеет никакого значения потому что если бы мы сейчас придираться начали говорить что о'кей если у нас студент какой-то группы - это отдельный конкретный класс и только в таком случае просто заработает э то о чём сейчас идёт речь а но это очень странная имплементация и я уверен сам Егор против такого кода ну потому что очевидно это неправильно то есть группа - это атрибут это что угодно но это не отдельная сущность а динамическая диспечеризация огромная тема на самом деле а про которую имеет смысл поговорить сразу делаю отсылку а если кто хочет вообще с этим разобраться очень круто и глубоко понимать я очень рекомендую читать Сикп и не только читать но и выполнять потому что вы там увидите как это прямо реализуется в языках где этого нет и очень классно показывает как оно на самом деле внутри устроено и что это за механика такая значит а что такое вообще динамическая диспечеризация про что здесь идёт речь это то самое что нужно для реализации а сабтайпинга или так называемого полиморфизма подтипом подтипов и когда говорят слово полиморфизм в контексте ООП то имеют в виду именно эту фичу потому что когда например функциональщики говорят слово полиморфизм то они имеют в виду немножко другой полиморфизм это параметрический полиморфизм или дженерики или темплейты там в C++ я думаю что вы так или иначе либо этим пользовались либо про это знаете просто не все знают что это называется полиморфизмом параметрическим полиморфизмом да так вот а полиморфизм подтипов сабтайпинг а это перефразируя вот слова Егора как бы механизм внутри языка который позволяет вызывать не просто метод который где-то заранее описан а вызывает некий шаблон что например там у юзера есть такой-то метод но на самом деле не у юзера а у интерфейса который он реализует или есть это динамическая утиная типизация то просто что там этот метод в общем-то присутствует в этом объекте и соответственно объект может быть другого типа то есть очень важно что речь идёт про типы а соответственно во время запуска этого кода во время его работы происходит подмена и выбор реализации в зависимости от того с каким типом объекта мы работаем то есть в одном случае вызывается один метод в другом другой а при этом прикладной код как бы как будто бы об этом не знает ну на самом деле не знает да то есть это типа где-то в кишках рантайма происходит так вот дело в том что динамическая диспетчеризация а это никакого отношения к ООП не имеет а это просто реально возможность вызывать разные имплементации на разных типах ну единообразно очень важно тут фишка именно в единообразии потому что только благодаря этому у нас появляется возможность типа подменять объекты а как он и говорил да что в одном случае у вас там яблоко в другом апельсин и вот он значит посчитал калории хотя опять же будут ли отдельные объекты под эти мм фрукты это большой вопрос ну к вопросу о том что а когда доходит до практики и проектирования там всё чуть сложнее будет чем кажется на первый взгляд так вот дело в том что в ООП то что саптайм обычно считается это очень простой вид диспетчеризации а он не просто называется так саптайм то есть по сути это диспетчеризация только по типу фактически когда мы вызываем допустим там user тоr run а хотя мне так не нравятся эти примеры но а будем говорить теми словами которые привыкли те кто про ОП слушает то в реальности а внутри проверяется а какой тип у юзера там естественно есть ещё история с проверкой наследования но не будем в это углубляться далеко и соответственно во внутренней такой сказать базе данных в памяти а хранятся таблички по которым идёт поиск э например в Джаваскрипте это чуть по-другому сделано там сделано через прототипы там цепочки по ссылкам смотрятся но идея всё равно одна и та же несмотря на то как это реализовано то есть у вас фактически идёт в динамике диспечеризации то есть выбор типа а какой собственно метод найти но эта диспетчеризация вообще-то очень простая она простая потому что работает только на базе типа а при этом она зашита в сам язык то есть вы не можете этим управлять а возможно для вас будет удивление кто сейчас вот про это услышал узнал или знал но вообще-то есть более продвинутые версии которые позволяют диспечеризацию делать гораздо более хитрую а на базе любого набора характеристик что позволяет фактически без использования а всяких разных конструкций которые обычно присутствуют в ОО языках реализовывать гораздо более мощную механику с гораздо меньшим количеством конструкций а хороший пример для этого - это кложа а-а ну и вообще это называется аа я забыл как он называется это протокол который ещё появился давнымдавно в Лиспах в КЛОже просто это заимплементировали тоже а забыл название сейчас не подскажу короче идея в чём у вас есть такое штука которая называется мультиметоды а фактически это реализация динамической диспетчеризации но более хитрым образом то есть а не язык за вас решает что а мы у нас есть типы и мы по типам будем а делать соответствующий выбор а язык говорит: "Смотри ты можешь написать свою собственную функцию диспетчеризации а по данным с которыми мы работаем" и вы фактически можете завязываться не на тип этих данных а вообще на всё что угодно вплоть до того что смотреть не знаю например разные методы будут вызываться просто в зависимости от того какой возраст там у людей а разные методы будут вызываться в зависимости от того в какой группе он находится как Егор сейчас привёл пример проблема в классическом вот ООП то что привязали к динамической диспетчеризации в том что вы обязаны создавать новые типы для того чтобы работала эта диспечеризация и все кто сталкивались с этой проблемой помнят как много об это сломано копий как много написано книжек как много написано статей как много споров в интернете о том что а правильно ли иерархию строить таким образом а правильно ли иерархию строить таким образом а-а а э если например у нас есть а-э метод приветствия который например для девочек должен писать одно а для мальчиков другое нам что снова придётся создавать новые типы ответ в большинстве случаев да либо вам придётся какие-то сбоку абстракции делать что часто делают заменяя наследование композиции например да но в любом случае вам придётся там внутри это учитывать и делать проверки на типы что кстати говоря является с точки зрения оп злом потому что вы фактически теряете возможность сделать реальную динаморфизм когда у вас типы могут добавляться легко и у вас вам не надо переписывать программу в такой ситуации вам придётся её переписывать потому что если вы начинаете if по типу делать что м если мальчики то одно то девочки другое то если добавится ещё третье что-то а очень видите такой современный пример у меня получился то вам придётся вот в тех местах где этот код написан его использовать а а как альтернативу делать разные типы ну это не очень круто то есть у вас конечно вы можете так сделать и более того не обязательно следоваться от пользователя это будут как бы отдельный типов в который идёт трансформация но здесь мы получаем то самое за что ОП очень сильно не любят хотя на самом деле это не проблема ОП в этом смысле это проблема вот того как реализована динамическая диспетчеризация а мы получаем ситуацию при которой это нерешаемо нормальным способом в этих языках где одиночная диспетчеризация по типу как в это же время происходит в той же Кложе вы в любой момент просто создаёте набор методов под любую задачу которые позволяют разделить даже а один тип а один объект э одну какую-то сущность ну например там студенты вот допустим да пример а по совершенно разным направлениям в зависимости от того какую задачу вы решаете то есть например вы хотите приветствие студентов делать на сайте а при этом оно зависит допустим от возраста вы сделали отдельный набор методов и сделали для них специальный метод который называется диat который э ну я извиняюсь он называется не дипач он я не помню как он называется в общем там задаётся эта функция в которой вы а описываете а во что в какой метод мы должны пойти работает она довольно просто то есть вы фактически на вход получаете эту структуру данных а смотрите внутрь неё делаете какое-то вычисление любое и сводите это к одному ну символу то есть к одной строке то есть фактически вы такой некий тип выводите сами конкретно нужный для этой ситуации поэтому например с её помощью очень легко реализовывать конечные автоматы поведение по необходимости и так далее и это гораздогораздо более продвинутая версия того а что есть собственно в тех языках а которые обычно принято ставить в пример и что я здесь ещё очень важного хочу сказать что по большому счёту несмотря на то что динамическую диспетчеризацию и полиморфизм подтипов а плотно ассоциируют ОП как видите реального отношения к ОП этого никакого не имеет и более того в не языках которые называются опязыками эта штука реализована часто гораздо более мощно и самое главное что появилось это очень давно то есть это в листпах было реализовано десятилетие назад я сейчас не буду обманывать когда но можно посмотреть а кстати вспомнил это про CL CL протокол по-моему называется да это было реализовано чёрт знает когда поэтому эта фича она во-первых не имеет отношения к ОП как вот концепции когда мы тут про объекты про связи про поведение а во-первых а во-вторых она гораздо больше имеет отношение даже в рамках объектноориентированных языков к типам чем к чему-то ещё вот такая вот история с динамической диспечеризацией и саптайм ну и вообще кстати если кто вот никогда не видел Кложу и никогда не видел мультиметоды я очень рекомендую вам посмотреть попробовать и заимплементить хоть одну задачу там где нужно вот поменять такое поведение это очень серьёзно вас прокачает как инженера и поменяет отношение к этим вещам вы просто увидите насколько мощнее это может быть и вы сами зададите себе вопрос: "А хм при чём здесь вообще ООП?" Хотя Егор совершенно прав с точки зрения того как работает конкретно вот объектноритированные языки и то что часто используется в той же Джаве и так далее то действительно там огромное количество логики завязано именно на такую подмену то есть фактически вот эта вот история про столп один из самых главных в OP - это сабтайпиing это правда то есть опять же он сам по себе не привязан но вот именно в OP - это типа один из главных столпов действительно невероятным образом влияет на то как выглядят программы написаные в объектноориентированном стиле и как вообще в целом идёт работа там потому что все вот эти вот проблемы связанные с выбором реализации по типу приводят к тому что мы создаём вот эти вот иерархии объектов мы создаём параллельные иерархии мы говорим о композициях и так далее и так далее и так далее это одна из причин там внутри произойдёт диспетчеризация нашего запроса она мне интересна это даёт нам возможность снизить сложных программ с помощью абстракции мы снижаем сложность комплекси она падает поскольку я работаю с фруктом мне всё равно яблоко это или сливо у меня в голове меньше когнитивных процессов происходит при обращении с этим фруктом я игнорирую детали абстракция - это игнорирование детали и второе инкапсуляция представим себе яблоко или фрукт инкапсуляция - это я бы сказал насильственная абстракция если динамический диспатч - это была добровольная абстракция программист сам говорил: "Я не хочу ничего знать об этом фрукте кроме количества то инкапсуляция - это насильственная абстракция мы говорим мы не скажем тебе кто мы такие" ну всё-таки тут надо добавить Егор сводит это к тому что динамическая диспетчеризация - это абстракция я скажу что это не абстракция а динамическая диспетчеризация это просто механизм а который можно повесить поверх любых данных а если в языке есть такая возможность а если вы работаете в объектноориентированных языках то вам придётся соответственно всё это делать на типах если вы работаете в языках скажем так более продвинутых вот в этом отношении как пример опять же к ложе как эталон наверное то вам не нужно иметь никакого доступа к этому вам не нужно думать ни о каких абстракциях вы просто берёте и реализуете любое поведение а динамическое для любых данных с которыми вы работаете вот и всё то есть это просто механизм выбора динамического выбора поведения там функции метода это неважно но к самой абстракции это не имеет никакого отношения честно говоря в этом смысле мы такие мы не скажем что мы яблоко или сливо мы спрячем информацию инкапсуляция ещё инкапсуляция ещё называется information то есть сокрытие информации мы закрываем и посмотрите на то что пишут известные нам авторы и гради Бучи и компании они говорят что э мы должны внутренности объекта интерпретировать как секрет как что-то что мы скрываем мы запрещаем клиенту знать кто мы такие он может по косвенным признакам деть он знает наш вес он знает стоимость он знает количество калорий он может сказать: "Ну наверное это я поскольку калорий много вес крупнее" то есть скорее всего это что-то более крупное наверное это яблоко но наверняка мы это знать не можем мы эту информацию закрываем вот две техники объекта ориентированного программирования которые э по утверждению многих авторов являются залогом ой тут дело в том что вообще как бы определение ООП а фиксированного не существует и вот это восприятие а м вещей разными авторами трактуются сильно по-разному и а когда один и тот же автор говорит об одних и те же вещах в разных контекстах у него может быть совершенно противоположное мнение относительно этого поэтому здесь даже и то что я говорю и то что Егор говорит и все эти ребята то что говорят это не является а некой истиной в последние станции то есть ООП в этом плане является очень сложной концепцией потому что например если мы говорим про императивное функциональное программирование там всё чётко функциональное программирование референциальная прозрачность или референсная прозрачность императивное программирование - это её отсутствие по сути если упростить это сводится к наличию изменения состояния давайте так присваиванию да вот в одних языках можно в других нет понятное дело что это шкала у вас не бывает идеального состояния идеального языка а функционального в котором вообще всё чисто у вас всё равно есть побочные эффекты там есть изменение состояния так или иначе просто оно пытаются как-то его изолировать в императивных языках там с этим сильно проще но поэтому определённый класс ошибок встречается чаще вот а с парадигмами типа оп крайне сложно и разные люди выде выделяют разные вещи я просто как пример могу назвать вот часто очень говорят там а и я даже сейчас говорил иерархии наследования вот это очень важно и так далее а вы очень сильно удивитесь но например м когда мы говорим про полиморфизм подтипов разбиравшийся сейчас а и я во время обучения людей там ну общению на технические темы что-то об этом спрашиваю или слушаю вот все как один говорят про базовый класс наследование и так далее а дело в том что наследование тут вообще ни при чём потому что речь идёт про имплемитацию а интерфейса а причём опять же речь не идёт про том что этот интерфейс явно существует в вашей программе например в рубе вообще нет понятия интерфейсов и в джаваскрипте и при этом там прекрасно работает динамическая диспетчеризация потому что там утиная типизация а но как бы в голове в своей концептуальной мы говорим о том что есть некий просто общий набор методов которые работают одинаковым образом а но типа разная имплементация но зато одинаковая сигнатура то есть тут речь про сигнатуру вот и в этом смысле наследование тут просто вообще не участвует никак и оно не нужно абсолютно при этом оно может присутствовать поэтому получается что то же самое наследование аэ вообще-то в большинстве случаев просто не нужно и может получиться так что я напишу программу в которой будет вот всё о чём говорит Егор и многие другие люди там будут и динамическая диспетчеризация палимфизм потипов и там будет инкапсуляция кто бы что ни имел в виду под этим и так далее и любой человек который посмотрит на эту программу я его спрошу: "Это объектноритированная программа?" Он скажет: "Это объектноритированная программа" более того я это много раз делал м возникает вопрос если вы называете эту программу объектноориентированной но в ней нету наследования вообще ни в каком виде то каким образом мы можем говорить что наследование является обязательной частью и столпом а объектноориентированного программирования я думаю что люди которые изучали логику в институте знают что такое базис помнят математику для них в принципе этого текладки которые я сейчас дал должны быть достаточно чтобы понять что это действительно так потому что если бы у вас наследование было неотъемлемой частью объектно-ориентированного программирования то вывод мог бы быть только один у вас в принципе программа без наследования не может считаться объектноориентированной если она считается значит у вас не может являться атрибутом а и в действительности чаще всего так и происходит то есть наследование - это такой в основном способ переиспользовать существующую логику в базовых классах чтобы её не дублировать а с точки зрения полиморфизма и всего остального достаточно соответствовать интерфейсам вот и всё а вот такая вот интересная штука про это а вот про инкапсуляцию мы сейчас тоже поговорим а значит здесь Егор говорит что это information hiing и мм существуют две интерпретации инкапсуляции во-первых действительно речь идёт про скрытие информации что это значит это значит что у вас есть некое внутреннее состояние которым вы не хотите делиться то есть вы как бы говорите что смотрите вот у меня есть объект а при этом а под объектом мы сейчас всё что угодно понимаем не объект прямо вот в объектноритированном языке и у него есть некоторые публичные вещи которые можно у него посмотреть спросить узнать а есть некое внутреннее состояние которое ну не надо давать людям напрямую менять и вообще иметь к нему доступ потому что во-первых если это происходит то мы не сможем изменять его со временем то есть например мы решили переписать нашу библиотечку люди завязались на какие-то данные а получается попа потому что они имеют прямой доступ и могут на что-то завязаться что потом при обновлении библиотеки всё просто сломается и нам будут говорить: "Ой вы сломали обратную совместимость" а мы им будем говорить: "А что ж вы завязываетесь на те вещи которые мы вам вообще-то не давали менять?" Это первое а второе - это инварианты то есть у вас дело в том что даже если есть какие-то внутренние данные которые вот вроде бы к ним есть доступ и всё такое менять их напрямую в структурах часто неправильно потому что они могут быть взаимосвязаны то есть например у вас структура может быть достаточно хитрая что при добавлении внутрь какого-то мм не знаю значения или там не знаю у вас массив например внутри есть и вы добавлю новый элемент у вас должно произойти пересчёт а каких-то других связанных полей соответственно если вы делаете это напрямую то у вас происходит очень простая история вы а нарушаете инвариант и данные как бы перестают быть консистентными ну и потом это может как-то вылезти тем или иным способом вот и поэтому когда говорят про инкапсуляцию часто говорят: "Вот смотрите у нас есть там private protected и public" при этом этот механизм он как видите сильно ещё завязан на объединение методов и функций потому что фактически когда мы говорим private соответственно у нас появляется доступ только через функции и вот мы туда всё это соединили и вот у нас получилось то что получилось но что я хочу сказать опять же если вы бы пишете или писали бы на разных языках вы бы увидели что это можно достигать совершенно разными способами дело в том что такой подход именно то как это принято в тех языках которые вот Егор в первую очередь имеет в виду например Java C++ и так далее это приводит к очень большому негативных последствий с которыми потом очень много борся кстати в этом плане очень хорошо видеть архитектуры классные от архитектуры которые не очень хорошие потому что когда у вас какая-то архитектура а при всей своей может быть красоте как это может в голове рисоваться приводит к тому что большую часть времени вам надо разбираться с самой архитектурой программируя то это в общем-то является на самом деле проблемой потому что она стала больше сложностей но очень часто когда человек уже в этом мире живёт и другого особо не видел он может воспринимать что ну наверное так и надо наверное проще нельзя наверное это необходимая сложность но нет это очень часто случайная сложность и в данном случае речь например идёт банально про то что когда вы всё это соединяете в одном месте а у вас в принципе появляется проблема расширения интерфейса добавления каких-то новых методов потому что если классы не ваши вы ими не управляете у вас получается попа вы можете пользоваться только стандартными штуками поэтому если например вы расширяете какие-то коллекции стандартные вам приходится писать свои короче появляется целая куча проблем которых в других ситуациях бы не было и из-за этого даже придумывают э например в котлине есть расширение экстеншна когда вы можете в класс что-то докидывать Java против этой концепции потому что это может там приводить к последствиям короче вся эта история на самом деле возникла только потому что в принципе есть такое объединение и вот какой там класс в начале заложили фиг вы его просто так поменяете если конечно вы не в каком-нибудь рубе или в джаваскрипте где у вас а в одном случае прототипы в другом случае открытые классы когда вы можете в любом месте программы просто дописать класс изменив его и повлияв соответственно на всё это невероятно мощная и одновременно гиперопасная техника которую конечно многие боятся но зато можно посмотреть как вообще в этой жизни бывает поэтому кстати вообще очень классно знать много языков писать на них потому что вот ко многим вещам которые Егор рассказывает начинаешь сильно проще относиться потому что ну не видя и не имея опыта написания скажем программ на Ирланги очень сложно понять как вообще можно жить в объектном мире без классов при этом у вас объекты будут гораздо больше объекты а в том базовом классическом смысле который Егор в начале рассказывал про а языки ещё шестидесятых чем или восьмидесятых чем а то что есть например в той же самой Джаве когда у вас вообще всё построено вокруг объектов и вы действительно оперируете сущностями которые в памяти работают параллельно обмениваются сообщениями то есть просто вот максимальная имплементация того что там говорилось так вот если возвращаться снова к инкапсуляции про которую он говорил а эта проблема

решается абсолютно нормальными способами и в других языках то есть например возьмите там тот же самый Хаскиль а собственно мм идея о том что это можно решить только сделав в классе Private и Protected она честно говоря не очень ну то есть я не знаю как так получилось что что люди которые придумали оп и его популяризировали смогли убедить весь остальной мир что это фишка ОП и типа без него этого нет не может быть и всё такое а то есть но при этом по очень важно эта штука она вообще никакого отношения к идее ОП вот та которая рассказывал в начале вообще-то не имеет а почему потому что я могу вам также показать очень классный мысленный эксперимент представьте что у вас есть написанная большая программа на Джаве и вы её уже не трогайте а допустим вы идёте и просто стираете из неё все прайвады и протектоты да у вас программа даже не сломается она просто продолжит работать то есть это очень надо хорошо прямо прочувствовать чтобы понять что фактически это не то чтобы защита от дурака хотя и это тоже но это не штука которая влияет на вашу архитектуру это не штука которая определяет целую парадигму программирования это просто механизм который дополнительно там присутствует для того чтобы обеспечить абстракцию но механизмов обеспечить абстракцию существуют просто миллиарды и для этого никакие объекты в плане слова объекты или классы не нужны а вы также а работая в том же ирланге оперируете понятием объектов вы это воспринимаете как объекты я вам даже более того скажу ещё больше объекты чем в той же Джаве по причинам названным ранее что у вас они там действительно в памяти сами по себе живут и принимают сообщения и так далее то есть вы чувствуете там ООП намного сильнее в этом смысле при этом у вас есть все те же самые штуки вы не можете обращаться напрямую к состоянию у вас есть только способ послать сообщение а оно внутри определяет как будет всё изменяться и всё это добро грамотно синхронизировано при этом нет никаких супер сложных концепций с прайватами протектами и так далее то есть вы прямо по дефолту просто открываете наружу только то что вы хотите открыть опять же конечно классно было бы если бы я прямо сейчас вам продемонстрировал или вы попытались это попробовать реализовать но и более того напишите в комментариях если кому интересно я думаю что что-то подобное замучу в таком лёгком режиме чтобы можно было сравнить это и увидеть вот так что история про инкапсуляцию меня честно всегда больше всего поражала тем как вот объектноориентированный мир а OP такого Java и C++ стайла смог убедить всех в том что только у них это есть и только у них правильная имплементация и вообще что это имеет какое-то отношение к ООПМ успеха ООП если мы сумеем правильно строить абстракции в нашей программе если мы сумеем правильно находить где-то я где то яблоко и где та груша и где тот студент и как между ними держать баланс то у нас будет в итоге программа удобная для программирования бертран Маер так и пишет: "Тот кто сумеет найти правильный ну на русский переводя правильный баланс между более высокого уровня абстракциями и низкого и и группировать более крупные абстракции из более мелких тот и победите" у того всё и хорошо получится а только отмечу что это никакого отношения к инкапсуляции не имеет которую сейчас ну приводит параллели такая логика о это первая часть о том как хорошо в мире объекта переходим ко второй части о том как всё не очень хорошо всё это здорово но объекты медленно работают вы можете написать программу именно так как я сказал всё собрать из абстракций всё построить на динамическом на динамической диспетчеризации на позднем связывании у вас в итоге всё будет работать очень да динамическая диспетчеризация естественно замедляет потому что у вас в фронтайме есть поиск выбор метода и так далее это очень сильное влияние оказывает на программу но очень важно понимать такую штуку что место в котором вам действительно нужен этот механизм не так много и это например одно из открытий которые я сделал когда вот из мира оп это было много лет назад может быть лет 13 назад там в 2012-13 когда я начал как раз я был тогда фанат маньяк объектно ориенритированных языков я перечитал все эти вещи а знал всё про паттерны и писал много статей на эти темы и в этот момент как раз познакомился с функциональными языками и тогда меня прямо это поразило когда я переключился в этот режим и понял что повальная инверсия зависимости завязка на интерфейс и так далее - это на самом деле ну перебор потому что э ну во-первых надо отделять систему типов от парадигмы программирования от не одно и то же потому что у вас как бы может быть нормальная типизация без необходимости всё это фигарить возьмите пример кстати современный Typeesриpt часто ли вы и много ли вы делаете там а классов например ну мало я уверен потому что например в той же самой Джаве у вас вообще шагнуть без класса практически невозможно и дело в том что аа когда у вас вот именно таким образом происходит работа когда а язык построен вокруг этой концепции у вас всё такое динамическое то собственно мы и получаем те проблемы и и те самые э подсказки что что-то не так с самой архитектурой то есть фактически динамическая дисциплиризация или вообще полиморфизм потипов как таковой или вообще в целом полиморфизм ну не потипов я уже говорил это мы можем называть как давайте называть это динамическая диспетчеризация в целом потому что опять же он может быть не по типам как в тех же самых мультиметодах ложи короче а эта штука в реальности нужна не так уж и часто и поэтому мне очень понравились языки в которых вы в пишете сначала в обычном режиме то есть в принципе вас никто не заставляет не то что классы использовать а вот эта вот история про диспечеризацию она не является основой вокруг которой всё построено потому что ну не так уж часто на самом деле это надо но в тех местах где это вам надо вы прямо конкретно делаете мультиметоды добавляете диспетчеризацию и у вас собственно это работает ровно так как надо там где надо а проблема языков которые называют себя объектноориентированными и Пайтона и Ruby и плюсов ну в меньшей степени правда у плюсов есть там понятие ещё виртуальных методов то есть там как бы явно действительно надо указывать что у вас он будет динамически диспетчеризацию надо использовать а Java C#P там и так далее в том что они это встроили так глубоко и настолько сильно что у них через это работает вообще всё и по дефолту и вообще в целом вы никак этого особо не избежите поэтому есть типа всякие хаки как там уменьшать количество а количество а объектов которые вы используете там какой-нибудь gamef пишите всё на статических методах и в итоге получается что мы создали систему которую сами пытаемся постоянно обойти то есть если бы изначально всех не заставляли так писать то и проблемы бы такой особо не было и это было понятно ещё во времена языка смолток статья девяносто первого года два её автора работали в то время над созданием языка сел язык сел был ещё более объектно ориентированным ещё более экстремально объект ориентированным по сравнению соток в нём совсем всё было действительно объектом в нём не было классов например там были только объекты и они говорят тут надо небольшое такое добавление а если я правильно услышал он же про селф говорит да селф во многом стал а прототипом для хорошее слово прототип потому что self по-моему это тот язык который активно начал использовать прототипы и JavaScript потом эту парадигму оттуда перенял насколько я помню правильно это и а про small TKк сейчас сказал Егор он говорит но селф пошёл ещё дальше там не было классов в реальности всё не совсем так в базовом раннем Смолтолке их было несколько версий не было классов и более того а классы были введены в нём именно из-за проблем с производительностью то есть как бы классы тоже а определённые проблемы доставляют и довольно серьёзные но там их вообще не было и поэтому было много проблем с производительностью так вот когда после этого Алана спросили о том о чём он там жалеет не жалеет он сказал что вот добавление классов было моей самой главной ошибкой потому что в вместо фокусировки на сообщениях и передаче сообщений м современный мир превратился в классоориентированное программирование что не соответствует его идеям объектноориентированного программирования ну и мы действительно этого много видим и вот эта подмена понятий она так или иначе произошла поэтому когда говорят сейчас про классическое оп у всех в голове возникают классы хотя на самом деле это не совсем так по крайней мере был и другое восприятие этого мира и и другое движение соответственно всё это слилось поэтому короче когда про это говорит Егор что вот он типа ещё дальше пошёл это не совсем правда а в чём-то может и дальше пошёл но явно дело не в классах потому что Алан Кей всё-таки сам был противником классов и более того по-моему это не он решение принял а их видение это там его какой-то помощник был но я уже сейчас не очень хорошо историю эту помню но блин вы не поверите когда-то я мог это прямо вот отскакивал у меня от зубов потому что я всё это наизу знал практически что объекты удобны для программиста но очень неудобны для компьютера объекты работают медленно компьютер не понимает как их ускорить как сделать так чтобы всё это шевелилось такой же скоростью как язык C и почему так происходит они дальше пишут что в правильном в чистом правильном ООП которое мы хотим иметь всё должно быть через отсылку сообщения вы должны отправлять это сообщение от объекта к объекту и ваше программирование должно выглядеть примерно так слева вместо того чтобы писать A + B вы должны писать A то + b вы должны брать объект А отправлять к нему сообщение плюс он должен получать ваше сообщение получать аргумент вместе с этим сообщением складывать а + b возвращать вам результат любому практикующему программисту понятно что это будет работать медленнее чем А + B чем просто операция плюс которая в современных процессорах занимает один такт пускай несколько тактов вместе с подготовкой данных и возвратами тебе вызов же метода плюс будет конечно занимать куда больше времени в процессе или представьте себе ещё третий вариант когда вы для операции плюс создаёте новый объект этот объект инкапсулируете А и Б потом у этого объекта запрашиваете чему же интересно равен этот плюс эти два варианта которые после первого они правильные опыта первый вариант неправильный а ну как я и говорил вот это вот понятие правильности неправильности а оно очень сугубо индивидуальное смотря чью школу мы выбираем а поэтому здесь я не могу говорить что Егор прав или не прав у меня например немножко другое восприятие этого опять же сформированное на базе там моего опыта программирования знания о языках и компьютерса там у Егора своё понятное дело тоже глубокое со своим пониманием но видите здесь всё равно у каждого своя штука скорее такое как вот картину какую-то сформировал в голове и считает правильным или неправильным потому что типа создавать третий объект при сложении двух чтобы у него что-то запрашивать по мне это немножко уже такой в параноидальный режим входит э потому что здесь за деревьями потерялся лес вообще для чего мы всё это делаем и какую проблему мы решаем к моделированию реального мира это уже вообще никакого отношения не имеет и более того а если мы вообще посмотрим на реальный код большинства систем мы увидим что э вот то что часто принято оп показывать вот смотрите у нас там микроволновка у нас там люди у нас тра-та-тта а потом ты открываешь спрингбд какой-нибудь и у тебя 2 млрд классов которые вообще никакого отношения к реальному миру не имеют какие-то секюрити провайдеры конфиги адаптеры прокси кыши и так далее и вся вот эта вот штука которая так классно весело рассказывалась она вдруг испаряется потому что ты понимаешь что большую часть времени ты не сущности создаёшь то есть ты берёшь какой-нибуд крупный проект он говорит: "Ну да у нас там ну допустим 500 сущностей" это уже достаточно крупный проект у кого-то 1.000 кто-то может ещё больше там инвойсы ещё что-нибудь но при этом ты говоришь: "А сколько у вас других-то классов?" А у вас там ещё 25.000 дшек э которые решают какие-то вообще совершенно утилитарные задачи причём в первую очередь задачи связанные с системой типов а даже и в этом плане вам даже как бы и классы не нужны потому что такие же проблемы есть и в языках без классов и там тоже они решаются вот с помощью подобных систем а и так далее короче всё это превращается в месиво и когда вы читаете про это смотрите вам кажется: "Ну вот вы посмотрели вы всё поняли вы идёте в реальную жизнь и а сели не поняли как что делать" особенно когда знаете возникают истории про то кто кого съел кошка еду или еда кошку или если у меня есть набор кошек как мне с ними взаимодействовать когда у вас какие-то обобщённые вещи появляются вся эта концепция конечно начинает плыть и поэтому есть попытка как бы это всё объяснить но она такая более религиозная как не знаю там на тему того что вот такое трактование и вот так вот правильно реализовывать а при этом другой человек скажет совершенно другое вот это как бы что касается правильности и сейчас тут ещё одну вещь я хочу сказать может быть кстати даже Егор про это скажет а может и нет есть забавная вещь связанная с вызовами помимо производительности ну с передаче сообщений вообще для тех кто не совсем понял что имеется в виду речь идёт о том что у вас не фиксированные методы внутри объекта а если кто писал вот на разных языках где это есть это вот в джаваскрипте это прокси можно через прокси можно реализовать это метод misмин в рубе это call какой-нибуд в PHP это в общем методы позволяющие а фактически когда вы вызываете метод у объекта в реальности нет никакого метода вы внутри вызывается один метод который условно назовём call куда передаётся собственно название сообщения это название метода снаружи а например плюсик и параметры а дальше внутри вы делаете всё что угодно то есть понимаете максимальный уровень как бы гибкости а но а там автокомплиты и так далее то есть у вас требуется очень много всякого геморроя для того чтобы это нормально поддерживать я уж не говорю про производительность и как показывает практика с точки зрения вот такой вот динамической природы это не так уж много где надо вот как пример м в рубе в рельсе очень популярно было когда она появилась это динамические методы выборки из базы когда вы пишете find email и передаёте сюда email метода такого нет у вас всё работает потом find email and name или or name и вы фактически можете конструировать абсолютно любую штуку то есть у вас внутри прямо есть просто мм определённая механика парсинга этого названия таким образом чтобы из него составить и скиль запрос крутая идея крутая но всё то же самое можно сделать нормальным просто языком который типизируется я имею в виду под языком дсэлькой какой-то да то есть Typeescriptрипt - это показывает как прекрасно можно это делать сумасшедшим просто уровнем возможности рефакторинга автокомплита и тайп-чека что всем остальным бесконечно от этого далеко вот кто не пробовал попробуйте поработать с такими штуками плюс опять же если мы берём а тот же Hernate или а Spring Data JPA у вас аа практически то же самое опять же понятно что в отличие от динамики требует чуть больше усилий но вы просто в интерфейсе репозитория описываете нужные методы и их тело то есть логика фактически генерация точно такая же просто это происходит реальная генерация кода поэтому у вас появляется автокомплит вы можете посмотреть исходник если надо и при этом у вас э в общем-то статический язык типизация и всё на свете есть места в которых всё-таки динамика прямо бывает нужна но такие вещи можно реализовать другим способом но в большинстве случаев вот такая штука не нужна ну я имею в виду вот так чтобы всех заставлять только в таком стиле писать ээ мы все обалдели бы если бы так было говорю вам как человек который много писал и пишет на рубе где этим часто злоупотребляют и к чему это приводит и более того вы вспомните когда такое было популярно ну не то чтобы такое но близко к этому когда в джаваскрипте там постоянно всё меняли в ядре прототипы и так далее и как от этого в конце концов ушли и даже в рубе можно посмотреть что патчинг как бы внутренностей от этого постепенно уходят и вызывают там нормальные методы то есть всё это меняется в эту сторону а потому что сейчас все понимают насколько важна типа безопасность насколько вывод типов удобный насколько автокомпли факторинги и многие другие вещи особенно в эру искусственного интеллекта где за вас всё это пишется и чем больше вот таких вещей тем проще это делать потому что у вас всё описано всё хорошо ну местами да динамики где-то не хватает но это намного реже встречается чем вот обратная ситуация а и последний момент который хотел сказать он касается передачи сообщений и конкретно арифметики это очень неочевидная вещь и я просто когда-то помню читал статью про это к чему это привело в Смалтолке представьте а Егор сейчас про это рассказывает как вот это типа правильное опять передача сообщений в Смолтолке так и было у вас когда вы пишете 1 + 5 там -7 x 10 а это именно передача сообщений и передача сообщений в этом смысле как бы с точки зрения порядка исполнения работает как вызов метода то есть когда вы пишете 1 то и дальше что-то передаёте у вас получается ну можно так визуально в голове поставить скобочки после плюса открывающую закрывающую и соответственно у вас э возникает некий порядок вычисления обычно это аппликативный порядок вычисления называется когда у вас сначала самые вложные аргументы функции вызываются внешнее внешнее внешнее в отличие от того же например Хаскеля где а а нормальный порядок сейчас я вот кстати прикиньте я так давно про это не говорил что уже забыл аппппликативный и нормальный порядок по-моему нормальный - это лейзи аппликативный - это как раз вот стандартный во всех языках э кошмар будет если я это перепутал ладно вы идею поняли что вот в Хаскиле в обратную сторону а здесь в прямую сторону то есть начало самое вложеное и таким образом оно постепенно раскрывается так вот в чём проблема почему я про это говорю потому что арифметика так не работает в арифметике есть понятие приоритетов невероятная проблема в том что у вас эти приоритеты исчезают целиком и полностью вы просто на методах не може ну это не реализовано в языке и более того по-моему это там особо так не реализуешь а фактически получается что когда вы пишете любую конструкцию арифметическую в смолтолке она работает вообще не так как вы ожидаете и её нужно специально допиливать э приоритетами скобочками и подстановками для того чтобы сработало то вычисление которое вам нужно вот такая вот интересная штука но я думаю всем очевидно что это конечно э несёт в себе серьёзные проблемы связанные скоти люди которые работали над языком Cell те двое которых я упомянул выше они работают в компании Google сейчас а этих кого я цитирую ээ один из них является техническим директором компании Google то есть эти люди они занимались интересной задачей пытаясь ускорить объектно ориентированное программирование у них не получилось как мы увидим позже но вопрос этот стоял давно ещё в девяностых в начале девяностых годов девяносто первые коды тогда это стало понятно немножко конкретики покажу вам чуть более поздную статью девяносто девятый год тоже текущий сотрудник Гугла сейчас Джек Пайпер они провели исследование чтобы показать на цифрах действительно ли насколько это медленнее насколько наши объекты медленнее работают чем если бы это чем операторы тот же плюс-минус и так далее и показали что проблема серьёзная если вы одну и ту же программу напишите в объектном стиле где у вас будет плюс в виде метода вы ту же программу напишите в традиционном процедурном стиле без абстракций без м без объектов опять вот повторюсь вот дихотомия неверная нет такого что либо вы пишете объекты либо вы пишете во-первых процедурно тут ни при чём а потому что напомню процедуры - это глобальное состояние это отсутствие возврата и так далее то есть абстракции есть в любом языке и в современных они просто сумасшедшие крутые классные и с ними никаких нет проблем а и при этом это не будет выглядеть так что такой: "Ой у меня нет объекта" нет там всё совершенно нормально и абсолютно такое же восприятие то есть в кстати вот это часто м такое восприятие что сложно людям представить себе если у меня нет слова объект если я вот например вижу написано а данные это что будет данные да также будет переменная называться usеer вы также будете оперировать юзером ничего такого а хороший кстати показатель в этом плане вот а го наверное да потому что у вас с одной стороны уже различают что как бы типы-то есть у вас есть там интерфейсы и это вообще относится к системе типов но это не относится к ООП и когда вы пишете в Го это не значит что если вы работаете с каким-то понятием что этого понятия не существует то есть у вас есть там юзеры у вас есть там всё что угодно что вам нужно для той предметной области с которой вы работаете да может быть более чуть деревянный язык в этом плане но вообще-то большинству наоборот это нравится а есть языки в которых также нету опли есть но оно другое в этом смысле и при этом всё там нормально то есть это будут нормальные абстракции то есть такой проблемы не существует а ну давайте так если Егор реально сравнивается с процедурным программированием он абсолютно прав но процедурное программирование не такие языки в продакшене сейчас в компаниях ну просто не используется какой-то либо legcy либо это школа где там не знаю пишут на них то вы получите серьёзное расхождение скорости они тогда тестировали Java 1 я вам показываю таблицу все цифры можно не смотреть посмотрите на те которые подчёркнуты цветом выдели они написали одну и ту же программу на Джаве и там и там было Java но в одном случае в Джаве были объекты в другом случае это были просто статические методы процедурные классические подкод и получилось что процедурном точнее объектный код работал условно 123 мсекунды а стильтран стайл как они его называю то есть без абстракций без объектов 6 мкунд в 20 раз в мене конечно трудно продать бизнесу концепцию которая удобна для программирования но настолько замедляет выполнение мы попытались повторить что-то в этом духе что-то подобное подобный эксперимент и написали программу для вычисления числа Фибоновича я думаю алгоритм Фибонащ всем известен но написали его двумя разными способами первый способ рекурсивно с помощью функций процедур что это Java то это некие статические методы то есть без абстракций без объектов и второй способ тоже рекурсивно но каждый оператор не могу ещё раз не остановить Егор продолжает это говорить что нет объектов нет абстракций а это не так глобально для ОП или не оп но это так в случае если речь идёт про те языки которые он конечно же упоминает то есть да там в этом плане конечно это просто банальные базовые структуры в которых у тебя там и прямой доступ и всё на свете но это просто особенность такая кстати тут ещё стоит сказать следующую вещь мм в принципе это раньше надо было сказать но я всё равно добавлю вот когда мы говорим про вызов через точку потому что вот о чём говорит Егор в том числе про удобство да что у вас вот вы думаете что вы вызываете там методы у вас там динамижат все дела а дело в том что это реализуется например таки подходом как Unified Function Call вот в ними в языке есть такая штука когда вы ну и в go похожая история но не до конца там ещё более развита она а когда вы описываете отдельно вашу структуру при этом опять же это не в плане того что вот просто голая структура то есть во многих языках это нормальная абстракция все дела но при этом вы можете отдельно и будете отдельно описывать соответствующие методы ну или функции а при этом вызов может быть очень разным и в этом плане Python больше всех помогает понять что на самом деле происходит когда мы пишем там user тоr run если человек не понимает как это устроено внутри языка ему будет казаться что ну это какая-то magic вообще там типа действительно run метода смотрите какая от функция отличается и Python говорит: "Ребят никогда не забывайте что здесь на фоне происходит очень простая вещь у вас вообще-то любые методы - это просто обычные функции и первым параметром просто передаётся собственно сам объект сама структура" и фактически а именно программируя на Пайтоне гораздо проще понять что это вообще-то синтаксический сахар ничего более и а языки определённые это уже развязали то есть сначала мы связывали всё в одно они сейчас развязали то есть вы отдельно описываете а структуру которая является опять же абстракцией во многих языках потому что вы не можете напрямую просто её там менять и к ней обращаться а отдельно описывайте методы для работы с ней для выборок изменений там и так далее при этом с точки зрения именно вызова это будет выглядеть как например user тоr run абсолютно такой же вызов более того там есть ещё альтернатива usеer там пробел run - это вот а больше такое как передача сообщения м есть такая концепция тоже в ниме как это сделано короче самое главное что самое главное что выглядеть это будет точно так же а при этом у вас не будет вот этого вот соединения которое ООП объясняется вот как бы частью инкапсуляции что вот смотрите из-за этого у вас объекты и на них мы это не просто вы вызываете функцию а вы типа выполняете действия над объектом вот визуально будет ровно то же самое поэтому фактически это просто синтактический сахар а про тут возникает вопрос типа а как он поймёт что это вот надо именно ту функцию вызвать э ну собственно по первому параметру потому что также это происходит в объекноретированных языках то есть мы понимаем что первым параметром там передаётся вот этот селф с этим типом ну и соответственно он соответствующую имплементацию нам достаёт вот и всё так это будет работать сейчас я подумаю я тут как будто бы что-то ещё хотел добавить ну ладно поехали дальше оператор у нас была функция точнее каждый оператор у нас был объект передача сообщений то есть вместо плюс мы использовали метод плюс так как я вам показал и вот что мы получили мы сравнили пять языков программирования java C++ C#P Go Паскаль паскаль тоже солиф правая колонка вы видите соотношение в 500 раз в 400 раз в 140 раз в 70 раз то есть ещё хуже ситуация чем в их случае ну они видимо были менее радикальным словом подхода потому что мы совсем уж утрируем ситуацию для нас в нашем объектном стиле написания программы Фибоначи всё объект в том числе операции плюс-минус и даже оператор если у нас объект JK21 между Jвой 1.2 и второй Javй ой что-то здесь прыгнуло ну да то есть причём здесь Фибоначи и объекты в этом смысле то есть я так понимаю что в Го они там куда-то это всё сами завернули ну это то самое да это уже маCH что называется а

попытка любую сущность описать как объект а это вообще какая-то философская даже я бы сказал концепция потому что если у нас есть задача получить динамическую диспетчеризацию мы уже много раз говорили в течение этого видео как это можно сделать если у нас есть задача получить абстракцию во многих языках современных особенно это всё классно встроено если у нас есть задача м там что ещё инкапсуляцию тоже она там во всех языках так или иначе решается короче всё так или иначе решается и в том числе другими методами просто а историческое наследие плюс то что часто не говорят слово объект вызывает ощущение что только в УП вот такого вида мы как бы модель которую мы в голове видим которую мы обсуждаем она соответствует тому что происходит внутри программы это не так и Джавой Дтьй никаких изменений не произошло как были объекты 30 лет назад медленные так они через 30 лет медленными и остались мы не сдвинулись как мне кажется ну я бы не сказал не на шаг мы какие-то оптимизации безусловно имеем в современных языках в современных виртуальных машинах но это конечно не те оптимизации которые могли бы нас приблизить к скорости процедуры к скорости без абстрактного программирования хотя бы на порядок чтобы мы были хотя бы в 10 раз нет мы медленнее в 100 а то и в 500 раз то есть на несколько порядков мы медленнее чем конечно же программист видя это не хочет использовать конечно же программист которому важно чтобы его программа работала быстро для бизнеса и удобно для клиента конечно же он сопротивляется использованию объекта я кстати даже немножко уже забавно слушать потому что а как такое как будто немножко насилие происходит что типа он сопротивляется давайте его всё равно как-нибудь убедим и заставим потому что это чистая некая концепция действительно немножко религиозно получается то есть понятное дело м идея что у вас есть абстракции и к ним есть определённый уровень доступа а поверх них можно делать а диспетчеризацию опять же не только по типам но например более глубокую это всё классные просто прикладные элементы программирования которые да в нужных местах можно и нужно применять но как ни странно смотря это видео я ещё я не то что хотел быть таким радикальным но как будто я радикализируюсь чем больше смотрю это видео что парадигма построенная что у вас всё только через это она конечно ведёт к гораздо большему усложнению ситуации появлению огромного количества мм подходов а принципов программирования и так далее построенных вот вокруг этого кстати один из ярчайших примеров вот у меня было видео по Solidду solid во многом а как раз применим ну не весь там то есть как бы там можно об этом немножко порассуждать но глобально он такой очень объектно ориентированный вот заточен под такие языки потому что если вы сейчас с солидом придёте в какой-нибудь опять же ирланг на вас так посмотрят типа хм что-то непонятное ну не в том смысле что там нету хороших идей но они скорее такие идеи больше из хорошо делай хорошо будет а но вот с точки зрения того что ты пошёл и применил там принципы определённые к языкам в которых нету классов это ну выглядит как натяжением совы на глобус да можно конечно рассказывать что ну Кирилл же как же single responsibility а много раз про это говорил это принципы которые очень неформальны а это супер неформальный принцип потому что всегда всё зависит от угла зрения они на самом деле никакой пользы особо не несут и каждый раз каждый интерпретирует это как хочет как бы классно они не звучали потому что когда мне начинают рассказывать про респонсибильность я говорю: "Вот я всё приложение на фронте могу в одном классе написать одно приложение одна ответственность да а буду ли я не прав?" Я считаю что я буду прав а потому что это слишком неформально вот и всё вот ну и это опять же куча других примеров можно привести кстати здесь также можно про паттерны сказать есть такая шутка всегда что чем больше паттернов в языке программирования тем больше собственно у него проблем потому что он а как бы заставляет а придумывать какие-то изощрённые способы для того чтобы решать какие-то задачи это конечно же не совсем так это шутка но в ней есть доля правды потому что немало паттернов которые описаны прибандит четырёх они фактически являются вариацией на тему динамической диспечеризации конкретно полиморфизма подтипов то есть например эти паттерны просто физически были бы не нужны в языках здесь мультиметоды потому что ты просто это просто бы решалось мультиметодом а тут вам надо прямо целые иерархии структуры интерфейсы а там и так далее придумывать для того чтобы это работало поэтому например людям которые пишут на языках с утиной типизацией даже банально а они когда это читают у них шарики за ролики заезжают потому что слишком сильно надо это адаптировать а под себя ну а какие-то вещи просто не нужны потому что там не знаю лямбды есть какие-нибудь то есть сильно всё упрощается немножко технических подробности что же там происходит почему они так тормозят почему когда я делаю А то п b это работает условно в 100 размереннее чем э было давно замечено не мои догадки давно было сказано что есть две причины замедления работы две причины этих ээ потери производительности у объекта причина первая - это виртуальный дисплант вот самый виртуальный диспект когда я обращаюсь к фрукту а там яблоко или слива то компьютер должен немножко подумать чтобы найти куда перенаправить из номае время это конечно же займёт время по сравнению с тем что я бы напрямую пошёл и сказал: "Яблоко посчитай мне что" поскольку я делаю такой динамический проход через некую виртуальную таблицу методов например то это занимает время это первая причина вторая причина - это локация объектов на куче кто программирует знает разницу между стеком и кучей стек - это память достаточно быстрая куча память а куча - это память куда более медленная когда мы хотим чтобы наш объект просуществовал очень короткое время между входом в метод например и выходом из метода то мы конечно его размещаем на стек когда мы выходим из метода объект удаляется но если мы хотим чтобы наш объект прожил немножко дольше и мы могли бы с ним работать не только в этом методе но и в другом месте передать его куда-то ещё мы должны его поместить на кучу а куча она медленная к ней нужно обратиться попросить выделить память пускай держит нашего объекта ему нужно всего лишь два байта мне всё равно нужно пойти в эту кучу выделить два байта памяти потом запомнить место этого этих двух байт запомнить указатель на этот на этот на это на это место в куче потом с этим указателем походить по программе поработать с объектом потом пойти обратно в эту кучу в диспетчер памяти в менеджер памяти и сказать: "Мне эти два байта больше не ну" вот эти запросы на выделение двух байт на освобождение двух тут если вы не против я пропущу понятное дело проблема есть надо решать и так далее но в целом это наверное не совсем та тема которую я бы хотел разобрать потому что мы сейчас разбираем идеи вообще оп и привязку их к ну к программированию скажем так поэтому я пойду дальше и сейчас конкретные пять примеров я вам покажу которые вам как программи программистам должно быть интересно что именно имеет сказать о чём именно идёт ребт не используем опыт первым статические методы или экоцентричные статические методы так их называет Дэвид Уэст автор одной из книг по объектам по объектному мышлению в жаве слева кверху вы видите как мы делаем наверняка многие из вас понимают что происходит нам нужно сохранить какую-то строку в файл мы превращаем эту строку в байты и дальше обращаемся к статическому методу WR и говорим ему: "Вот файл вот строка сохраняй" он получает два этих аргумента сам решает что с ними делать он сам знает как сохранять он сам знает что у него в руках он эгоцентрично и абсолютно эгои ну может быть эгоистично эгоцентрично скорее принимает все решения о том что к нему пришло он контролирует ситуацию не объекты которые ещё вчера были объектами до того как попасть к нему в руки а он игнорируя всю инкапсуляцию игнорирует всё что у них внутри он просто берёт те данные которые мы которые к нему пришли и сохраняет более грамотный более объектно ориентированный дизайн на примере слева внизу мы конвертируем строку в байты а дальше эти байты нам и умеют нам и позволяют сохранить себя в фай мы обращаемся к байтам и говорим: "Сохраните себя в файл" они сами разберутся как это сделать они знают как вы они у них знания о себе инкапсулируют они скрывают для нас это секрет как они будут сохранять себя в па и этот дизайн называется абстракцией дизайн сверху называется процедурным и оперативным программированием ничего общего не имеющем с open да он написан в синтаксис Джа да нам кажется что это объекты потому что ну смотрите байты у нас тут как будто бы объекты и путь куда мы Ой

а тут дело в том что второй способ а и я не то что там прямо максимально против наоборот если посмотреть ээ в Rруub который в этом плане сильно дальше Джавы пошёл и я поскольку на нём тоже много кода пишу там вообще доходит до того что вы просто можете написать ну например 1 точка а mon гол и получить из этого дату на оди месяц назад как вам такое вообще в большинстве языков такого нет я вам более того скажу мне просто вот чисто на пользовательском уровне э ну это правда не совсем честно потому что это не совсем руби это расширение Rails которое как раз меняет ядро то есть фактически патчит числа добавляет туда такую возможность а вы начинаете работать с датами вот таким форматом и это настолько естественно настолько удобно и настолько как бы классно что я очень страдаю переходя в любой другой язык то есть какой бы там не придумывали язык он же всегда просто через вызовы даже если это цепочка вы вызываете это не на данных данные вы внутрь передаёте да а и вам надо что-то оборачивать туда а и а когда особенно там складываете даты вы читаете даты я всегда в других языках обращаюсь в документацию и я думаю что вы все это делаете вот руби один из немногих языков или наверное единственный в моём случае а где для большинства задач вот ты когда концепцию этих вызовов понимаешь а ты на английском можешь составить любое предложение и получить ту дату смещение диапазон какой тебе нужно и это заработает там если ты будешь передавать куда угодно это очень круто это фантастично и это очень приятно но я с другой стороны понимаю насколько это и опасная техника и как это часто не работает в других случаях представьте себе вы работаете с числом в любом другом месте и это число на самом деле если вы посмотрите список методов вы просто обалдеете от того сколько там всяких нерелевантных вещей то есть у вас число одновременно и дата и одновременно и это и всё пятое десятое и здесь получается то же самое что то в данном случае hello в байты - это ещё ладно можно как-то сказать что ладно строчку там в байты перевести но в какой-то момент могут появиться методы которые строчку переводят совершенно во что-то другое и у вас получается что в каком-то месте в котором вы работаете в контексте строки как строки вдруг строка на самом деле ещё при себе имеет 30 методов которые вообще имеют отношение к конкретной предметной области а если это не строка тогда вам придётся какие-то там обёртки генерить и так далее и тогда непонятно почему здесь мы работаем сту байт потому что тогда в таком случае и для байтов нужно какую-то обёртку делать и более того а даже появляются ещё более сложные концепции когда позволяют именно вот так доопределить методы в каком-то конкретном контексте что типа мы давайте вот тут строку воспринимать таким образом но естественно если она выйдет за рамки там возникают сложности короче это супер всё сложно что рождает очень непредсказуемое поведение всей системы добавления кучи методов в тех местах где их вообще быть не должно я уж не говорю про то что опять же когда вы начинаете всё это соединять с другими вещами то есть вот тут вот это такой пример специальный подобранный как бы логичный там save to тра-та-тата но очень часто бывает такая комбинация разных сущностей которые вот так вот в цепочку не выстроишь и ну ничего хорошего из этого не получится и поэтому история про статические методы она действительно выглядит чуждо но даже Java не может из неё обойтись и опять же я за то что нет никаких статических методов есть просто обычные функции и в том месте где надо вы можете добавлять а вот например такой стиль а либо диспечеризацию то есть потому что почему здесь Егор про это не говорит потому что в Джаве никто не воспринимает что статика может быть использоваться с диспечеризации потому что она не может так использоваться да в отличие от той же кложи которую мы много раз сегодня упоминали вот поэтому а всё это можно сделать как бы инструментами которые используются только в нужных местах а языки в которых есть и это и это одновременно они существуют и гораздо больше чем кажется на первый взгляд а наверное один из самых классных примеров этого Camл просто посмотрите когда вам нужно вы просто берёте и применяете это О в том виде в котором вам нужно и получаете многие штуки которые работают похожим образом более безопасно и лучше красивее и интересней вот а поэтому вот этот вот формат второй несмотря на то что в некоторых местах это выглядит невероятно сексе привлекательно классно удобно а в большинстве реальных ситуаций где начинается вот этот жонглирование большими связаными вещами превращается в тыкву сразу вот плюс это всё нерасширяемо ну даже просто вдумайтесь вот такой save to pass а при чём здесь вообще путь а если я в базу собрался сохранять а если по сети а всё у вас сразу всё плыть начинает куда мы сохраняем это объект но мы потеряли абстракцию ээ потому что достали данные проигнорировали инкапсуляцию и дальше работаем с данными первая большая бетап современного - это наличие статически ну кстати да вот говорит по поводу потеряли абстракцию да нет не обязательно у вас же есть всякие итераторы то есть э речь не о том что эта штука напрямую в кишки лезет да то есть вот вы потому что в save to он точно также pass передал а в file write он передал bytes которые получены через get bytes вот а понятное дело что во втором случае get возвращает объект но этот объект-то внутри в save to в любом случае будет будут извлечены данные поэтому это не совсем корректно в этом смысле выражение вот ну тем более кстати опять же если уж хочется такого п никто не заставляет нас передавать в WRй именно байты как просто набор байтов допустим хотя тоже коллекции нужны как бы а как без них-то а туда можно передавать gets из второго примера который является объектом и внутри в любом случае вам придётся достать из него байты при любом раскладетических методов и их интенсивное использование программистов почему это программисты делают да потому что медленно будет работать код который снизу снизу слева написан код который сверху работает быстрее который слева мее который снизу медленнее конечно программистыра первый вариант теряя объектналити к сожалению а давайте так я сейчас последнюю штуку скажу и на сегодня попрощаемся значит есть ещё один такой интересный момент а многие механизмы которые есть в Джаве считаются невероятно важными без них невозможно работать на базе них построены самые объектноориентированные штуки из серии контейнеры для DI контейнеры это орэмки фреймворки и так далее они построены вообще-то на рефлексии а reflection API - это что это собственно то самое что позволяет вам влезть внутрь программы обойти все ограничения и на основе каких-то там метаданных на основе там не знаю посмотреть список методов запатчить конструктор вызвать создать объект без конструктора и так далее и так далее без всего этого просто все эти штуки были бы невозможны поэтому речь даже идёт не про то что там статические методы - это не оп вообще ядро а большинства фреймворков а и каких-то тяжёлых серьёзных э софтин таких библиотек для вообще работы ну это в основном такие инфраструктурные да которые нужны для работы они очень сильно завязаны на всякие разные вот в разных языках там ансейвы на прямую работу с прямым доступом ко всему подряд вот и рефлекш API в этом плане тогда несмотря на то что сам Reflection API выглядит как объекты фактически он позволяет делать такие вещи которые полностью нарушают всё что сейчас Егор рассказывает и без этого жить невозможно ну к вопросу о том что ну нельзя упаковать мир в вот в эту концепцию то есть нет ничего плохого в объектах нет ничего проблем в объектноориентированной парадигме просто делать первично вот эту концепцию э это поиметь такое количество проблем в тех местах где раньше было просто то есть натягивать пытаться это натягивать это просто капец с таким же успехом можно ну я не знаю всё всё что угодно другое то же самое кстати в функциональном стиле то есть если вы начинаете натягивать везде неизменяемость ну попробуйте в Хаскиле просто рандомно пологируете код в каких-нибудь частях то есть вы там тоже получаете миллиард проблем на пустом месте но хотя бы там есть логика потому что язык для этого создавался это в том числе какая-то такая теоретическая конструкция а имеющая некую красоту математическое описание и смысл вот поэтому там есть дисбаланс в эту сторону в такую теоретическую красоту и чистоту но он э специально там создан но есть языки в которых всё довольно неплохо сбалансировано вот и там как бы вот этим просто никто не занимается об этом не говорят и с этим нет никаких по сути особых проблем и все остальные вещи просто как опции да то есть у тебя объекты опции диспетчеризация - это опция и совершенно прекрасно всё работает вот ребят я на сегодня прервусь в принципе наверное там дальше было ещё интересно и возможно если вы посмотрите это видео и скажете: "Кирилл слушай зачёт давай дальше я с удовольствием закончу и сделаю вторую часть" при этом а будет очень классно я думаю егор как минимум частично хотя бы так помотает посмотрит 100% найдёт где я тоже ложанул сказал какую-нибудь херню и что-нибудь неправильно понял в его понимании и он хочет возразить возможно мы даже частично это обсудим на нашем общем созвонии либо он сделает реакцию на на реакцию вот короче я бы очень хотел это пообсуждать а может быть мы с ним просто в отдельном видео конкретно это разберём в общем ребят если вам понравилось и это очень в тему пожалуйста пишите в комментариях что вы об этом обо всём думаете согласны ли вы больше с Егором согласны ли вы больше со мной какое-то у вас третье мнение а через что вы сами проходили и стоит ли продолжать в таком стиле и закончить например это видео а очень буду на это ориентироваться потому что если да я с удовольствием дойду до конца мне точно есть ещё что по этому поводу сказать всем большое спасибо не забывайте подписываться на канал Организованное программирование в Телеграме где я про все эти вещи рассказываю и ещё маленький нюанс я недавно запустил давно хотел недавно запустил а клуб который называется Hexlet клуб где а я собираю ребят кто уже работает в разработке кто хочет расти в первую очередь профессионально прокачивая свои хардскилы возможно устроиться в зарубежной компании на более высокие должности в общем а в этой системе в этом клубе мы занимаемся тем что помогаем а под нами я имею в виду в том числе ребят которые там участвуют помогаем прокачиваться технические скилы проводим оксобеседование и так далее и так далее в общем много всего это только сейчас началось там уже больше 1.000 человек и я собираюсь очень активно м эту часть развивать я там есть общаюсь это наверное единственное кстати место публичное где я постоянно присутствую а в общем если вы ещё не там присоединяйтесь здесь на экране где-то будет ссылочка ну и соответственно в описании всем спасибо пока до новых

встреч เฮ

№45  Разбор лекции Егора Бугаенко о настоящем ООП  | Организованное программирование
Broadcast by