Ну изи же - пузырек нужно было обернуть в декоратор "ComparableПузырь" потом накидать эти пузырьки в список, а для списка сделать декоратор "SortedList"
Создаешь класс Value, в нем 2 метода equal и greater, которые принимают на вход другой объект класса Value. Создаешь класс Sorter с методом sort, который проходит по обектам и сранивает их и возвращает отсортированный список. На самом деле слова докладчика верны и на таком принципе работает react js, но он заехал не на ту конференцию и выбрал не тот язык, в котором его концепция реализована. Ему прямая дорого в ФП, а именно в хаскель или immutable.js
Я понимаю что это ирония, но для тех кто не вьехал: Что за объект "сортировка"? Объекты называются не по принципу "что он делает", а "чем он является". Объект не может являться "сортировкой". "Пузырьком" тоже. У вас есть объект "какие-то данные", делается декоратор "отсортированные какие-то данные", у которого сортировка происходит в конструкторе (насчёт этого не совсем уверен, кажется это не совсем соответствует идеологии Егора, но хрен с ним, суть не в этом). Вы инстанцируете "отсортированное", скармливая его конструктору уже существующее "неотсортированное", у вас получается объект, содержащий отсортированное. Только не надо просить от меня объяснить почему якобы я считаю что всё это правильно, я ничего не считаю, а просто передаю вам мысль оратора как её понял я.
Докладчик пытается изо всех сил притворяться, что данных не существует, и пытаться писать программу так, будто есть только поведение, а данных нет. Именно поэтому сферическое ООП в вакууме, которое он проповедует, так и не вылезло из песочницы, ведь за её пределами данные и способы работы с ними игнорировать невозможно, а в распределённых системах они и вовсе выходят на самый первый план. Способы разбиения данных, компромиссы CAP, как мы будем разруливать неизбежные конфликты и partial failures - вот о чём болит (или должна болеть) голова у стоящих разрабов. А не о том как пообъектнее изобразить живой объект комментарий который умеет себя редактировать. Тьфу.
вы путаете архитектуру и реализацию. В вашем примере "стоящие разрабы" должны заниматься написанием алгоритма, а в видео речь об архитектуре проекта, которая неизбежно скатывается в уг из-за непонимания, как вообще ее строить. Тьфу (с)
@@acd2377 да, конечно же мы можем измерить габариты табуретки. Вопрос геттеров больше философско-концептуальный, чем имеющий практичное значение. Вреда от геттеров немного, но обычно они указывают на "код-смелл". Вам вдруг зачем-то понадобились параметры табуретки вместо того, чтоб взять и сесть на неё. Потому что объект табуретка создается для того, чтобы на нем сидеть. А если вам нужны габариты табуретки -- то вам стоит спросить их у объекта "столяр", который построил табуретку и знает её структуру. А не у самой табуретки. В общем, если вы разговариваете с табуреткой -- в вашей жизни и вашем коде, что то определенно идёт не туда. Вот как бы вкратце о геттерах, но повторюсь, что все эти принципы не могут быть строго формализированы и просто следует воспринимать как указания. Есть где-то геттер -- посмотреть, а действительно ли он нужен, и зачем внешнему объекту понадобились внутренние данные другого объекта, возможно внешний объект делает работу, которую должен делать не он, а запрашиваемый объект. С сеттерами все сложнее и интереснее. Да, как бы это дико не звучало -- нужно выбросить старую табуретку и купить новую с другим цветом. Представьте себе, что табуретки в магазине по три на рубль, и для вас это финансово вообще не проблема. Но логичный вопрос - - почему нельзя перекрасить? И тут уже надо понимать почему у Егора текут слюни на иммутабельные объекты. А все потому, что они очень удобны и надёжные. В примере с табуреткой -- у вас есть табуретка черного цвета и в любой момент времени, разбуди вас в три часа ночи в воскресенье под дулом пистолета и спроси какой цвет у табуретки -- вы без тени сомнения ответите что чёрный. И будете правы на 100% и всегда, и во веки веков, аминь! Чего нельзя сказать о мутабельной табуретке с сеттерами. Вы никогда не знаете, а не покрасил ли её сосед, пока вас дома не было. Вы приходите домой, ничего не подозревая, с разгону садитесь на свежепокрашенную табуретку и у вас вся ж...э-м-м.. седалищная часть брюк теперь ярко красного цвета. Вот чем плохи мутабельные объекты. Вы никогда не уверены в них на 100% и должны проверять "иф (табуретка не крашена") { сесть на таберутку } елзе { ждать пока высохнет краска }.
@@acd2377 "Модель мира" и "доминация" это лишь для красного словца. В действительности неудачные аналогии только вносят дополнительную неразбериху. Я просто отсеиваю их сразу и рассматриваю только практическую сторону вопроса -- чем мне это облегчит жизнь как программисту. Геттеры и сеттеры плохи именно с практической точки зрения. (Хотя это и странно выглядит поначалу.) А вся философия - это шелуха.
@@acd2377 Понятие "модель объекта реального мира" означает упрощенный вариант - имитацию некоторых свойств объекта реального мира. Думаю суть иммутабельных объектов в моделировании только нужных свойств, избавлении от ненужных состояний и лишней сложности из-за этого (Сложность от бесконечного числа классов, видимо, не учитываем). Получается при инстанцировании объекта табуретки мы создаем спроектированную в классе модель табуретки из реального мира. И этих моделей можно создавать сколько угодно с любыми свойствами в любой момент времени. Это наша виртуальная модель любой табуретки из любой точки пространства-времени реального мира. Например, увидели вы табуретку голубого цвета - у вас в сознании создалась модель иммутабельной голубой табуретки, затем вы посмотрели на табуретку желтого цвета - аналогично и с ней.
По сути он предлагает процедурное программирование на манер ООП. То, что раньше было статическими функциями, теперь оборачиваем классами и гордо называем ООП.
Судя по-всему, он и сам особо не вьезжает в принципы ООП вообще и инкапсуляции в частности. Все рассмотренные случаи на слайдах - говнокод и он не постиг Дзена. Хотя как примеры, как делать не стоит (плодить классы ради классов и оба! - ты в ООП) вполне годно
на самом деле он концептуально это метод приложения. Т.е. запуская приложение ты запускаешь метод маин, который подразумевает наличие своего приложения. Ты же не вызываешь main в коде?. Вообще его можно вызвать?. Т.е. если хочется поржать только, то можно шуточек найти, когда люди стараются сложную тему донести
Класс 2dvector, его используют другие объекты, некоторые используют его координаты раздельно для проверки каких-либо условий. Получается для каждого использования я должен генерить новый класс потомок, инкапсулирующий работу с этими координатами. В пределе по доп.классу для каждого использующего класса. Это уйма лишней работы, а обозримость и анализируемом то кода падает до нуля - я должен елозить по огромному дереву на каждый чих, чтобы понять, что происходит. Безумно.
Почему getters и setters это плохо? Почему извне мы можем делать всё что угодно с этими данными? Отнюдь нет. С данными делать можно только в рамках дозволенного функцией. Например у нас есть функция set с параметром int. В неё можно поместить число в диапазоне 0..255, а мы поместили -15 или 300. Нам не нужно прописывать отдельные случаи с такими данными, функция set это уже реализовала. В SFML есть класс sf::Text, в нём есть функция setColor. Через setters тексту нельзя применять цвет? Как иначе тогда? 36:14 У нас есть 2 варианта: файл переименовывается в той же папке или по новому пути. В чём принципиальная разница между методами Rename() и setName() если тело обоих методов одинаковое, разница только в трёх буквах.
Не являюсь сторонником выступающего, но что касается сеттеров, то с некоторыми оговорками он прав: любое изменяемое состояние (класса) ведёт к проблемам, особенно в многопоточном окружении. Ибо его надо синхронизировать. А любая ошибка при реализации синхронизации приводит к трудно воспроизводимым и исправимым багам. И даже правильная реализация может приводить к частым блокировкам потоков и потере производительности. Кроме того, и вне многопоточки код с отсутствием изменяемого состояния гораздо проще читается и воспринимается. Если вы хотите изменить состояние объекта, то, как автор и сказал, просто создаёте новый на его место. В этом случае ваша функция setColor вернёт новый sf::Text - дубль старого, но с изменённым цветом. Так это работает в ФП во всяком случае.
@@zachemny По поводу setColor и sf::Text. Я увлекаюсь кибербиологией, эволюционным моделированием, там каждая секунда на счету. Если заново создавать sf:Text с его атрибутами (цвет, шрифт, размер, атрибуты стиля, толщина, цвет контура шрифта, позиция на экране и т.д.) всё это отдельные функции и при каждом создании нового текста ради цвета придётся вызвать 8 функций. Я подозреваю каждый вход в функцию, если она не inline кушает ресурс процессора. Способ который предлагаете вы, возможно более читабелен, но боюсь медленней чем тот, который использую я (ради цвета вызываю только setColor()).
@@UFO26 Ну, я не пытаюсь навязать вам данный подход. В каждом конкретном случае он может оказаться неудобен или даже неприменим. Хотя выглядит несколько странно, если у вас моделирование привязано к изменению или выводу текста, обычно эти задачи разносят, и там, где идут хардкорные вычисления, текст не генерируется. Хотя, возможно, я что-то неправильно понял. 8 функций для создания объекта вызывать по идее не нужно, вызывается клонирование предыдущего объекта с изменением его свойства. Но поскольку иммутабелен весь текст, то клонирование придётся повторить для всей предыдущей части части составного объекта (графа объектов). Вообще же иммутабельный подход к структурам данным считается более медленным, зато приводит к упрощению кода (особенно многопоточного). Ускорение тут достигается засчёт более эффективного распараллеливания. Ради каждого изменения приходится изменять почти весь граф объектов (начиная с корня до тек. узла, т.к. они все иммутабельны). Но, в то же время, это можно делать в отдельном потоке, что может в итоге оказаться даже эффективнее, чем блокировать весь граф для др. потоков на время внесения изменений. Привнесение изменяемости для классов в этом контексте считается оптимизацией и выполняется только тогда, когда все остальные средства уже исчерпаны, а скорости всё ещё не хватает.
обьект file не должен иметь геттер, который мог бы вернуть path. А как тогда реализовывать его же декоратор (не знаю, почему сабж использует этот термин)? вот хочу реализовать mmap, или типа того же file input stream, или random access file? в конечном счете все равно придется получить path, что и сделали в JDK
Дистиллированное ООП не стоит делать самоцелью. Институты одобряют. Индустрии важнее практичность. Элементы ООП могут удачно уживаться в одном проекте с элементами не-ООП. Если ООП в реале так часто протекает, значит дороговато все-же его ТО? Выход из ограничений ООП - это не всегда плохо, а иногда даже очень даже удобно.
@@inbuckswetrust7357 ну тогда не понятно, а зачем статик метод пихать в класс, состояние объекта которого он не использует? Почему это не может быть просто отдельная функция? Зачем плодить сущности, если смысл тот же?
На мой взгляд, помойка классов хуже помойки функций. Потому что из функций мы составляем алгоритмы. Все предельно ясно. А классы могут (и обязательно будут) находиться в очень сложных отношениях между собой, из которой логику работы сложно понять.
@@grace-pt4hwпотому что имя класса, в котором объявлена эта функция даёт дополнительный контекст читателю кода - это раз. Куда ты предлагаешь засунуть эту функцию, если не в класс? Физически где ты собираешься писать ее? Это два.
"Неужели нельзя посреди кода в объект вписать какое- то число, которое вдруг показалось важным? Это же мой любимый паттерн погромиста!" Как подобные товарищи будут реализовывать многопоточность на уровне задач (а не данных), которая реализуется через асинхронное выполнение (а значит нет последовательного кода, следящего чтобы все было согласованно)? Да не писали они никогда ничего серьезного, вот и воют, что у них забирают возможность писать код- лапшу.
у автора много видео с "критическим" мышлением, как по мне обычный самопиар и мне люто интересно, где же он там в spring увидел кучу геттеров? это вообще то штука о DI с бинами на секундочку. я о том, что мне кроме POJO , нигде там геттеры и не нужны особо были.
Не сложно, покуда вам пофиг на фрагментацию кучи. c=a+b a и b - экземпляры класса вводных данных. c - экземпляр класса суммы. На каждой операции создаём и удаляем объекты в куче. Вместо тривиальной перегрузки сложения надо написать по классу на каждый вариант расстановки типов данных по слотам вывода и параметров перегруженной функции. И создать по уникальному имени для каждого класса. ... А потом кто-нибудь изобретёт перегрузку для имён классов.
От написания кода на таком двинутом ооп страдает оптимизация и едва ли его сильно проще подлерживать в масштабе больших проектов П.с. досмотрел до вопросов и понял что я бы очень долго спорил с этим докладчиком П.с. сколько в параметров у типичного персонажа или предмета в игре? Конечно тут есть наследование, но на выхлопе разобратся в коде пусть из маленьких но 100 000 классов, будет нифига не проще. Например шлем, классы предмет>броня>клас ксотюма>шлем в конечном объекте нам надо хранить данные на удары по какой части тела он действует, заерывает ли он лицо, сопротивление к разным типам атак, и это может быть ещё тонна параметров и на выходе не всегда получится разбить всё до уровня 4-5 публичных методов, и опять же ююигроку на экран в инвентаре по хорошемы нужно вывести какието параметры этого шлема, и других айтемов в его инвентаре и т.д. почему не сделать гетер? Просто гетер и не написать просто функцию которая соберёт данные со всех надетых айтемов брони для того чтобы выводить эти данные, надо дёргать отделбный метод, который будет помимо зюсвоего объекта ходить в таблицу и отдавать туда свои параметры? Так чтоле? Я не претендую на гуру геймдева, я просто не понимаю людей которые несут подобное и прямо таки жаждут писать на чистом ООП, и опять же, пусть даже мы будем максимально дробить классы, они требуют больше ресусорсов платформы для исполнения проги, функции или статические методы могут работать быстрее уже просто на выхлопе компилятора со стандартными настройками, а про ручную оптимизацию этого выхлопа и настроек компилятора я уже промолчу.
@@denisviklov4596 Не, там на каждый фрейм придётся пересоздавать всех персонажей и часть ландшафта вроде деревьев и травы, ведь они каждый фрейм меняют своё состояние))
Не знаю по мне слишком заморочено, есть люди которые едят только мясо, они говорят есть овощи не правильно вовсе. Есть и другие психи кто одну траву жрет и приводит 100500 пруфов что так правильно жить. Но истина посередине, плодить миллиарды микроклассов это утопия, но и создавая объекты надо думать надо ли пихать везде сеттеры, и думать о доступе, так же использовать оптимальные функции для экономии ресурсов железа, и тд, не надо кидаться в крайности, если вам дали много инструментов это не значит что есть суп надо вилкой, держа её пинцетом зажатым в левой ноздре.
мнение что класс - это просто набор методов и свойств ведёт нас обратно в язык С... а понимание что класс - это живое существо ведёт нас далеко вперёд.... в 41 тысячелетие. тонко
Доклад очень интересный, но несколько раз был задан хороший вопрос , а как эта концепция сказывается на производительности. Не на пустом же месте появились move семантика и cow. Помню в одном из проектов после профилирования, обработка строк занимала 80% машинного времени.
37:12 - аналогия класса String, любое присвоение переменной нового значения пересоздает объект. в принципе логично. ведь файл новый. значит и объект новый.
Непонятно в чем разница то, ну не хочешь большой список иметь простых методов, будешь иметь херову тучу своих микроклассов :) типа супергибко но ужасно неудобно пользовать это все.
Так классы нужны для того, чтобы объединять объекты, которые будут иметь схожие характеристики и схожее поведение. Если объекты будут без привязки к классам, тогда будет много дублирующегося кода. Разве не так?
Нет, классы для этого совершенно не обязательны. Иначе процедурное или функциональное программирование не могли бы существовать в принципе. Помимо наследования через классы существует прототипное наследование в js, а самое главное, существует такое явление как "композиция".
По моему опыту: схожие объекты объединяются классом без логики и всеми публичными полями, либо стуктурой. После этого создаются классы-конвеер которые эти объекты обрабатывают. Но это не ООП. Происходит сепарация данных и логики, как это делается в функциональном программировании. Объектное же подразумевает инкапсуляцию логики и данных внутри одного класса.
Причем смотреть доклад нужно ПОСЛЕ просчтения Effective Java. Правда прибегут потом фанатики и свидетели быстрого С++ и расскажут как плохо пересоздавать объекты
Конечно не полностью согласен, но разумные мысли есть. И зря его все здесь так поливают. Именно так и должно идти развитие, путем анализа и отсечения полезных или не полезных идей.
Идеи понятные, интересные. Столпы ООП (типа Гради Буча) вобщем-то и учат изначально такому мышлению. Однако потом наступает реальный мир, где вместе пятидесяти классов тупо проще сделать один и допустить, что в нём часть свойств могу быть null. Тчк. И когда тебе твой бизнес-манагер стучить по голове со словами "когда будет сделано?" по 10 раз в день, ты рано или поздно будешь всё чаще и чаще выбирать менее time consuming вариант. Так работает практика. За очень редким исключением, когда какие-то решения могу быть проработаны наперёд и ясно, что они дают некую гибкость на будущее и позволят в будущем сэкономить labor cost. Однако это тоже зачастую нивелируется реальной ситуацией, где есть масса проектов, которые толи проживут ещё месяц, толи нет. И далеко не всегда в реальном мире прям нужно заморачиваться с правильностью ООП.
имхо - суть и смысл этого доклада улавливается быстро и понятно, но нельзя возводить в абсолют такие вот "методологии" разработки, потому что в дальнейшем расширять проектный функционал будет практически невозможно, потому что (если я правильно понимаю) код начнет расти в геометрической прогрессии, а вместо "ненужных" поджей появятся "столь необходимые правильные объекты"... но если поджу можно просто дополнить, то те самые правильные объекты нужно будет экстендить... то есть проект перестанет быть компактным по самой структуре... короч это опять палка о двух концах. искать золотую серидину опять придется каждому самостоятельно.
я вообще не программист, а ядерный физик с образованием математика, но спрошу:) Чем микроклассы по сути отличаются от обычных процедурных функций типа того же fopen? это не отход ли от ООП? И чем декораторы с новыми методами отличаются от классов, наследующих примитивный класс File?
декоратором ты же оборачиваешь функции или методы классы и даешь им новое стандартное поведение, можешь думать о них как о pre-hooks, дюже удобная штука, про класс вообще не понял к декораторам отношения не имеет
Ничем кроме покупки книги этого товарища) Есть такая поговорка - если у человека есть лишь молоток, он везде будет видеть гвозди. "НЕ используйте хибернейт и спринг в написании программ на джава"... Мне действительно жаль себя и всех людей которые потратили время на просмотр этих фантазий на тему программирования.
5:06 Потому что, первое, объекты объектами, но в нормальном, не экспериментальном коде требуется оптимизация, а она с трудом возможна без процедурного подхода (без понимания процедур, тех процессов, которые стоят за всем). Недаром наиболее производительный софт писался и пишется на Си. В результате получается, программист должен мыслить одновременно и объектами, и процедурами. Второе, отсутствие нормального, единогласного, общепринятого, прозрачного объяснения основ. Нигде нормально не расскажут что такое инкапсуляция и полиморфизм, зачем они нужны в ООП, и почему ООП без них невозможно. Даже у апологетов противоречащее на сей счёт мнение. Касательно объектов, ООП это и то, что даёт инструменты программно описывать объекты, выделять участки кода, представляемые как объекты, и объектами является все в коде, любая буква. Это всё путает и грузит. Третье. Не только компьютер, и человек мыслит процедурно, особенно в том, что касается наук или каких-то навыков.
Амм,нет. Человек в наууах мыслит объектно с сохранением инвариантов бизнеса) матрица-объект,вектор-объект,алгебра -объект. Как то так.процедурно никакой науки нет.
31:17 это какой-то лютый пиздец, декоратор чтобы читать построчно, давно уже все придумали два разных метода, при этом делаем отдельными методами все для подготовки файла к чтению, потом тупо имплементируем прочитать все или прочитать и вернуть строку, в первом случае тупо будет определять границы файлы и возврощать строку, во втором по символ переноса строки и проверять что не выходим за границы файла на следующей итерации.
в целом интересно, но не очень понятно как это применить в суровой реальности enterprise. мне пока сложно представить, как можно этой концепции строго придерживаться на практике. нам с фронта может прилететь большая котлета с частично заполненными полями, которых в принципе много. это все ифами и декораторами разруливать чтобы распихать по маленьким классам? я думаю спринг, хибер и иже с ними были созданы не от того что их создатели процедурно мыслят, а как необходимое зло.
Если фронт способен пуляться такими котлетами, значит с самим фронтом что-то не так. Но в антрепризе да, куча легаси и совершенное отсутствие времени, средств и желания что-то переделывать. Кобол вам в руки, и будет полное антреприз-счастье, да.
то о чем он говорит для этого есть целая аббревиатура, не помню как называется, там этих парадигм и принципов туева хуча, господин Немчинский хорошо об этом расскажет
Интересный доклад. Было бы любопытно посмотреть код Егора, чтобы узнать насколько строго он сам придерживается названных правил, ведь это довольно непросто. Хотя по-моему верно для ООП. С другой стороны, в java добавлены элементы функционального программирования. Так нужно ли так строго соблюдать постулаты ООП ? Не лучше ли найти компромисс? В любом случае дана пища для раздумья.
"У нас появляются со временм много костылей, код сложно понимать, хочется его выбросить. По этому ООП это будущее!" Звучит очень похоже на... "У нас кривые руки, нам нужно 200 слоев абстракции ООП. Мы страдаем и вас заставим!"
дело в том, что мыслить можно как угодно, хоть объектами. Можно придумывать и "живые сущности")). Но в итоге все сведётся к обычному процедурному коду)
@@princessmary5556 всё необходимо так или иначе транслировать в процедурный конвейеризированный код, которым является последовательность операций АЛУ процессора. Из-за этого все ограничения машинного кода будут унаследованы любым ЯП любой парадигмы любого самого высокого уровня, на котором пишет программист. Поэтому если среда выполнения не может транслировать высокоуровневый код в эффективный процедурный код, то код эффективным быть технически не сможет, какая бы моча философам в головы ни била.
Зачем говорить, что "мыслить объектно" - это облегчение для программиста, если практика оказывается показывает, что для программиста естественно мыслить процедурами и программисты даже используя ООП все равно применяют процедурное мышление? Может надо перестать слепо верить в то, что объектно-ориентированный подход дает какие-то преимущества? И просто работать по улучшению методик и практик процедурного программирования?
Правильно. Писать надо так как проще. Так как мыслишь так и пиши. А не так как навязывают. Я как-то класс какой-то заумный из 1000 строк на php переписал на процедурный в виде 5 функций обычных и понятных и в итоге код занял около 300 строк. Скорость выполнения специально измерил - она абсолютно аналогична. Читаемость кода значительно улучшилась. И чего где какие преимущества? Просто крупные компании навязывают какие-то тенденции и все как дураки слепо идут в этом направлении.
@@KKZ_5000_RUB в итоге по сути ты последовал идее Егора, разбив большой умный объект на простые и от этого выиграл. Просто ко всему этому добавляется иммутабельность, которая порождает thread-safe, конечно, не все она надо, ну тут уж.
Ещё не досмотрел, но если из его понятия объекта просто убрать термин "живой", то получится абсолютно всё тоже самое, как он это для процедурных языков описывал. Какие-то словестные спекуляции без сути
Попробуйте пописать код в таком стиле и вы увидите как она из императивного превращается в декларативный. Термин "живой" придумал не Егор, это из книги Object Thinking.
Ну используйте слова: "самостоятельный", "наполненный своей волей", "реализующий свои желания"... Смысл в том, что к объекту надо относится как к самостоятельной личности.
@@avikuloff И как одно противоречит другому? Вы тоже существуете во времени и пространстве, но реализуете свою волю (например, в предыдущем комментарии попытались отстоять свою точку зрения).
@@ivanaaa6049 Когда говорят, что объект "живой" имеют ввиду, что он подобен объекту реального мира, то есть он существует во времени и пространстве, обладает состоянием и имеет поведение. Живой, самостоятельный - это все от лукавого. Объект может быть зависимым (подчиненным), говорить о воле и желаниях вовсе не приходится, я человек - у меня есть воля и я могу реализовывать свои желания, а кирпич не может, но от этого кирпич не перестает быть объектом.
Да, Сергей дело говорит. Но это не значит, что сетеры и гетеры вообще не нужны, это значит что их использование не должно нарушать инкапсуляцию и вообще здравый смысл)
Вроде что-то и не плохое говорит, но ответы на вопросы вконце порадовали. "А что сделать если я хочу переименовать файл, а у меня нет метода сетнейм" - спрашивает один дилетант. "А сделай метод сетнейм, только назови его ринейм" - отвечает второй. Становится очень интересно, когда говорят что ООП должен отражать реальный мир, и при этом дают какие-то непонятные рекомендации, когда на том же примере с классом "файл" очевидно, что изменять, переименовывать, показывать путь этот класс вообще не должен, в реальном мире как правило менеджер файлов должен работать с файлами. Это как в реальном мире говорить автомобилю перекрасить себя в другой цвет самостоятельно, а не обратиться с такой просьбой к мастерам.
"изменять, переименовать" - это "ринейм" получается что и есть. "показывать" - это ложится на вызывающий код, который такой же инкапсулированный для внешнего мира
Python SmiSoft автомобиль, поменявший свой цвет - это уже другой автомобиль. Даже по документам. Think about it! И ещё, то что он СЕГОДНЯ синий никак не отменяет тот факт что ВЧЕРА он был красный.
@@megasuperlexa2 Это проблема возникает из-за того что бумажные документы до сих пор на руках у нас. Поэтому и автомобиль другой и человек другой человек когда меняет паспорт :) потому что так проще системам учета но не человеку :)
Егор говорит о простой вещи: декларативность. О том, что нужно отражать бизнес -логику в объектах, чтобы с кодом было проще работать. Поэтому между setName() и rename() огромная разница. Никому же не приходит в голову назвать этот метод changeStringTypeFieldValue(). Просто представьте, что вам пришлось понять, что делает программа только лишь читая стектрейс.
То, что выступающий считает "идеальным ООП" было реализовано в языке Smalltalk чёрти-когда, тогда же не прижилось и умерло. Следовало бы тогда сказать и про то, что объекты, по сути, должны посылать сообщения друг другу и сами решать, когда на них отвечать и отвечать ли вообще, и про контексты объектов, и ещё, и ещё...) Идея, конечно, интересная, но уже позно. ООП сформировано таким, каким его видел Н. Вирт (алгоритмы+данные в единой коробке). Перечисленные выступающим фреймворки - уже де-факто стандарты и завязаны на текущей реализации ООП в java (взять, хотя бы, IoC в Spring который привязан к геттерам и конструкторам). И от этого всего уже не отказаться.
z0r pwnd Да не прижился Smalltalk, только посмотрите как человек радуется кода, изобретает Smalltalk заново. А не прижился он, так люди просто не захотели думать по другому. Да и для того чтобы работать в стиле который излагается в лекции нужна ide или система на подобие Smalltalk систем разработки, но надо сказать что и они не идеальны, но разрабатывать в них одно удовольствие.
По правде говоря, Smalltalk так и не реализовал полноценную отправку сообщений (там это по сути сахарок над методами), в отличие от Erlang/Elixir. Поправьте, если я ошибаюсь
Ага, а если файл у нас в пару гигабайт, мы, наверное, хотим буферизованое чтение. И навернуть потом сверху «вернуть контент одной строкой». После чего вся концепция простого базового иммутабельного объекта рассыпается. Достаточно посмотреть на реализацию IO без прикрас, чтобы понять, что это не самые простые вещи. Кроме того, мне непонятно, что в таком случае делать с классическими задачами, которые мутабельности требуют - например, percolation, где у тебя может быть на входе двух или трехмерный массив на мегабайт, в котором клеточки открываются, и с каждой клеточкой нужно чекать, соединились ли грани. Каждый раз генерить новую карту на мегабайт? Удачи с 10к изменений массива. Реализовывать STM отдельно по каждому поводу? Затрахаетесь. Объясните, умные люди?
Можно получить синглтон не применяя сам паттерн) ты просто инициализируешь его через спринг. без бреда про живые объекты мы прожить можем а без IoC нет) В Spring сли надо ты вместо синглтона делаешь ему другой scope ('session' например) и он будет сущесвовать один но на время сессии юзера в веб приложении. т.е @Autowired MyService myService...и к нему уже обращаешься через переменную
@@РусланСитников-у4м Ваше право так считать. Но это не значит что это одно и тоже. Ответ Николая больше предлагает написать свой ApplicationContext "Который будет знать, сколько объектов текущего класса создано"
В итоге никто и не пишет "настоящих ООП" программ. Может быть, это не очень хорошая идея? Зачем заставлять себя "мыслить объектами"? Ждет ли нас реальное просветление в конце этого пути? Может быть современное процедурное программирование на практике достаточно неплохо работает? В сочетании с элементами ФП и ООП почему этого недостаточно? Некоторые аспекты ООП наверное актуальны, но стоит ли все вращать вокруг этого? Есть ли доказательства того, что ООП это тот самый правильный, идеальный подход к дизайну приложений? На каждый пример плохого ООП приложения ответ обычно в стиле No True Scotsman, а хороших примеров за пределами книг и нет. Многие новые ЯП, опять же, процедурно-функциональные с интерфейсами. Вообще, чистые парадигмы -- это сомнительно, и попахивает религией. Про геймдев я и вовсе молчу, тут во всю Data Oriented Programming и Entity-Component-System, массивы и хендлы.
Согласен, я хоть и начинающий программист, сделал для себя вывод: чистый подход про который говорит автор - это конечно бред. Вообще ООП - отражает наш реальный мир и он проще для понимания. Инкапсуляцию нужно делать самой сущности, которую представляет объект если это путь к файлу то он не должен меняться, ну а для каждой возможности объекта создавать декоратор - это абсурд.
Не пишет-то не пишет, но вот от количество багов в софте повсюду заставляет задуматься, а что же делать, чтобы их не было. Я попробовал подход Егора на практике и был сильно удивлен тем, насколько легче мне стало писать юнит-тесты, насколько более читаемым стал код и насколько надёжнее в целом стал мой код. Проектировать - да, сложнее, но всё остальное стало очень сильно легче.
>> Есть ли доказательства того, что ООП это тот самый правильный, идеальный подход к дизайну приложений? Нету. Зато есть множество свидетельств обратного.
TH-cam Channel какой подход егора? Про иммутабильность он правильно рассуждает, и про нуллы - явно где-то прочитал. Но какой его подход? Ведь его нет. У него получается гора мелких классов с 1 методом, которые непонятно как использовать - про composition root он сказал только одно: это очень плохо )
Была такая присказка, что первый язык определяет все остальное. И тот, кто начинал с бэйсика считай инвалид. Вот собственно первый звоночек у меня был в самом начале речи. Потом оратор попытался давить авторитетом, что он вообще тут не первый день, не насрали. Это был второй звоночек. Третьим звонком, после которого я поставил видео на паузу и стал писать этот коммент, стали слова о том, что сначала все программы на ООП красивые, а дальше полная жопа. И так, товарищ оратор, надеюсь прочитаете. Вы не осознаёте всю проблему, вы такой ведь не первый и не последний. Вы привыкли смотреть на все снизу вверх, детали реализации у вас во всем на первом месте, для вас ООП показался враньём только потому, что вы пытаетесь его применять для удовлетворения вашего обычного рабочего процесса, вы видите только сложность инструмента и простор для возможной ошибки. Большой опыт может не только разнообразить знания, но и наоборот сузить, закрепив какую-то одну идею, доведя ее до локально вашего пика, а все остальное может не только не развиваться, но и забыться. Это иллюстрация проблемы опыта 20 лет и опыта 1 год, но 20 раз. Программы с развитием и навешиванием на них реализаций требований всегда с течением времени скатываются в говно. Говно вообще можно на любом языке написать. Но как только человек начинает нормально вырубаться в ООП, код поддерживается лучше. И да, ООП скорее не о программировании, а об организации проекта и его ведении и архитектуре. Вот и все. Не с того ракурса смотрите, разнообразьте представление о мире, не разочаруетесь.
Мужик молодец! Объектам надо отдавать всю задачу, относится к ним как если бы у них была свои желания и воля. Это похоже на фирму, где каждый сотрудник отстаивает интересы своего направления. Можно вспомнить поведение программ в фильме "Матрица"- именно так надо относится к объектам. При таком подходе программист просто выбирает наполнение программы этими самостоятельными сущностями. Погромисты негодуют :)
Точно, пример с Матрицей вообще прекрасен, особенно после его анализа на канале "ЧБУ". Кто не смотрел очень рекомендую - "Морфеус - программа" называется
И тут мы приходим к функциональному программированию, где данные не меняются. ООП это натягивание концепций реального мира на программирование. Вот в реальном мире есть объект пациент, сегодня к него есть аппендикс, завтра нет. И что надо порождать новый объект?
@@princessmary5556, конечно. ооп не занимается реальным миром вообще. ооп это всего лишь инструмент управления императивным кодом. и программистами императивного кода.
Не использую ООП вообще, никаких классов тоже не использую, а тупо функциями все всегда пишу. Интернет бизнес свой. И у меня нормально. Есть две квартиры и машина. Путешествую еще часто. Так что это все просто инструменты. Которыми можно пользоваться, а можно и не пользоваться. Не нужно думать, что знание ООП и умение мыслить как-то иначе что-то вам даст какие-то преимущества. Самое главное пишите так как думаете, как вам удобнее. А все эти тенденции и модные тренды это пусть в гугле и фейсбуке там сами на своем ООП пишут. Мне оно даром не нужно. Кода больше получается, читаемость хуже. Понять код зачастую тоже сложнее. И зачем оно нужно такое? Так же ка и стрелочные функции и всякие сокращения я тоже терпеть не могу. Код должен оставаться быть понятен вам даже если прилично поддали. Или проснулись среди ночи.
Просто разные концепции В одном случае цель это эффективный бизнес. Первичен доход, а не инструменты. От инструментов прямой выгоды нет, главное чтобы оно хоть как-то работало, денюжка капает просто за счет бизнес-процессов В другом случае цель это эффективное ремесленничество, мастерство. Первична производительность этого самого мастерства, количество заказов в единицу времени: чем больше заказов выполнишь, тем больше заработаешь, никаких альтернативных бизнес-процессов, кроме самого ремесленничества, тут нет, денюжку приносят только закрытые заказы. Тут уже вступает в игру разница в инструментах: одни инструменты позволяют достичь результата раньше и с меньшими усилиями, чем другие, но они сложнее и освоить их труднее, как например голый блокнот против навороченной IDE, или например самописный код против фреймворков и библиотек. Тут проявляется разница в подходах: в голом блокноте весь процесс производства ты выстраиваешь сам, а в IDE ты вынужден учить как с ней работать и осваивать те методики разработки, под которую эта IDE проектировалась, точно также и всю архитектуру самописного кода, все требования к нему ты тоже определяешь сам, но при использовании фреймворков и библиотек ты вынужден обучаться тому, как их использовать, вынужден использовать именно тот подход, под который они были спроектированы, а значит вынужден осваивать и использовать ООП, паттерны, заиметь понимание основных алгоритмов и структур данных, их свойств, ведь все это там внутри библиотек и фреймворков зашито, ожидается на входе, и получается на выходе, и с этим хочешь-не хочешь, но придется работать, чтобы повысить эффективность своего мастерства. Без фреймворков и библиотек писать тоже можно, но это явно займет несравнимо больше времени и затрат, чем развернуть фреймворк или подключить библиотеку и сразу получить значительную долю итогового функционала
POJO это фреймворк! Вон оно как... Получается автор не рекомендует использовать ЛЮБОЙ JAVA класс не унаследованный от какого-то специфического объекта. Фтопку JAVA, LOL)
Автора замкнуло просто си++ и джаве в основном на джаве, автор старый ничего нового в жизни не хочет и поэтому не понимает, что забивать рубанком гвозди такая себе идея. Вся штука в том что современный программист для эффективной работы должен как минимум уметь в три - четыре языка, знать сильные и слабые стороны и использовать под конктретные задачи, а не так что взял джаву эту и громоздишь монолит на миллионы строк из говна и палок. Вторая проблема заказчик который редко когда знает и понимает что ему надо и получается: "потсоны тут проект фигня мне тут бамбуковый шалаш без сортира" к концу проект: "ээээ я чот в Дубае побывал нахуй мне этот шалаш давайте его в небоскреб переделаем, бабки есть я плачу"
Доклад интересный, но действительно любопытно было бы увидеть код какого-нибудь web-приложения с таким подходом. Индустриальный стандарт все-таки Spring, Hibernate. Никуда от этого не деться. А в них такой подход, видимо, не уложится..
Доброе время суток всем добрым мальчикам и девочкам столь увлеченным програмированием и и всем тем кто по уши в этом замечательном мире . Я случайно наткнулся на этот ролик и являюсь начинающим из всех начинающих наверно с низов в этой сфере , понравилось програмировать и нравится логика и идея этого занимательного дела пока месь на уровне хобби . Я иногда писав код сталкивался с какой-то невидимой стеной и понимал что процесс програмирования для меня какой-то не комфортный , что я мыслю и представляю себе это иначе ... Этот ролик поставил все на свои места , я понял для себя что я как минимум мыслю именно так . Большой спасибо автору , желаю ему успехов !
Я не программист, но класс это объект? file сам по себе же класс описанный в библиотеке, то получается мы создаем класс f из класса? И чем меньше класс и их больше то это же "простыня". И всё это вместе превратится в процедурное программирование. Комп все сделает все равно по порядку, он не понимает человеческое. Упрощу, например возьмем объект - человек (весьма крупный, у него много чего другого, руки, ноги, голова, потроха и т.п. вплоть до молекул и атомов можно) и это будет очень большой непонятный код как вы говорите. Надо разбить его мельче. Но как это правильно будет тогда? Объясните пжлста. Я так понимаю ООП - всё объекты и все свойства его закрыты. Например, если открыть объект файл F, то извне никак не должен изменятся. Если у него много параметров то так и должно же быть, Не? Как объект человека разбить? Руки, ноги, голову всё расчленить надо?
@@Anonimus_13 да, да, именно так. Только хотябы,например, вплоть да ногодков опишите. Атрибутов стало больше? Надо разбить мельче говорит автор. То как будет это выглядеть?
@@SSSuzd автор намеренно утрирует, чтобы донести смысл. Вам часто приходится писать приложения, где бизнес интересует модель некой сущности с такой детализацией вплоть до молекул?
зависит от задачи, в данном подходе главная логика, будешь широкой композицией объектов, каждый из которых совершает небольшое действие, нужно лишь понять, в како момент ворваться и что добавить.
Ну хорошо, допустим геттеры нельзя. Есть такой вот объект файл, представляющий файл, открытый моим самописным блокнотом. Пользователь нажимает "сохранить как" и ожидает оказаться в директории, где этот файл находится и с уже введённым именем файла, чтобы его слегка изменить. Вопрос: где взять имя файла? Тащить по системе от открытия до сохранения? А где хранить? В глобальной переменной? Выглядит как костыли на ровном месте. Допустим, сеттеры нельзя. Вот есть у меня лейбл на мордочке, в котором периодически меняется текст. Например - панель состояния текстового редактора, в которой пишется имя текущего файла (которое там класс Файл говорить отказывается). И так, мы открыли файл, ииии... Как нам поменять текст нашего лейбла? Удалить и создать новый лейбл? А какой в этом смысл, если понятнее и менее затратно будет сделать setText(). Ну и без статики же тоже нельзя. Конечно же, есть у нас в редакторе функция, например, закомментаривание-раскомментаривание строки. Класс String у нас Final, туда мы ничего не можем положить. Куда класть методы работы со строками? Создавать класс без состояния, нарушающий вообще всю суть ООП, ради того, чтобы просто не делать статический класс? Тоже попахивает костылями и пуризмом.
@Yevhen Matasar Допускаю, что иногда такой подход оправдан. Но применять его везде и всюду просто потому что "так надо" - глупость. Представил установщик, который при каждом изменении значения прогрессбара удаляет его и создаёт новый, со значением на 1% больше)))
Не понимаю помешанность на иммутабельности. Есть действительно подходящие ситуации. Есть не слишком. Как мне быть с той же машиной в момент езды? При каждом изменении угла, на которое повернулось колесо, создавать новую машину? Или колесо новое создавать? Это ни как не коррелируется с реальным миром. В реальном мире объекты не плодятся при изменении своего состояния. И состояние их меняется постоянно... А если машина состоит из большого количества деталей, то все они изменяют свое состояние и я постоянно буду вынужден проходить нехилый такой цикл инициализации машины. Ясно же, что это правило годится только для атомарных объектов как файл или объект даты...
автор говорит, что у машины есть намного меньше свойств, чем вы ей приписываете. Машина может иметь например цвет или раму с колесами, а если вы поменяли раму с колесами на раму с гусеницами, то это уже другой объект будет. А в случае с поворотом колеса - то для этого будут меняться состояния объекта рулевого колеса, например, машина при этом не меняется, колесо тоже не меняется - оно как было колесом, так и осталось.
Доля истины в этой идее есть. Особенно если не фиксироваться на объекте как на программной сущности, а представлять его себе как сущность информационную, как некую "душу", которая способна менять тела в виде программных объектов при необходимости, если рассматривать объекты как фрагменты данных, а не конкретные области памяти Только вместо декораторов стоит пользоваться разумной необходимостью Вам не нужен класс, который умеет всё. И вам не нужен класс, который не умеет ничего. В каждом конкретном случае вам нужно что-то конкретное, какая-то сущность, которая обладает строго ораниченным функционалом. Это не только ограничивает область контекста, но и стабилизирует архитектуру, делает ее жесткой и устойчивой. Вот от этой идеи и стоит отталкиваться. Да в принципе она и так везде используется, если посмотреть со стороны: одни и те же по сути данные проходят через множество слоев, но в каждом слое они обернуты в разные объекты с разными характеристиками. Когда объект находится в нижних слоях, он несет в себе множество "лишних" низкоуровневых данных, когда добирается до верхних слоев, в нем остается только самый необходимый минимум данных. И на пути от железа вовне и обратно объект множество раз "перерождается" в разных формах, с разными характеристиками Только в таком виде та концепция, которую докладчик пытается выразить, обретает хоть какой-то смысл
По поводу ООП. Вообще странным образом получается так, что отчего-то невозможно взять и сделать так, чтобы данные обрабатывались сами по себе внутри своего класса. В основном потому, что бизнес-логика на классы не пилится. Более того, сейчас все паттерны вроде dto, ecs и ioc направлены на то, чтобы отойти от ООП максимально далеко. Отчего у меня вопрос: а так ли нужно ООП?
@@KKZ_5000_RUB я попробовал пет-проект на функциональном языке написать. Там конечно не полноценная функциональность - F# все таки, да и я предыдущего опыта не имел и работал паттернами из объектных языков. Но в целом по мне за функциональными языками будущее.
Я всё жду когда Егор откроет для себя ФП. Я конечно понимаю, что сокрытие это основная мантра Егора, но сокрытие фактически нужно для борьбы с mutable, и особо не нужно в ФП. Если Егор на подобное согласиться, то наступит покой в его душе. А я бы посоветовал ему честно попробовать Rust в течении пары месяцев.
По мимо минимального набора команд, которые делают язык Тьюринг полным, весь остальной синтаксис существует для упрощения процесса программирования (что обычно подразумевает упрощение поддержки). Т.е. да доп.синтаксис ООП языков (по сравнению с процедурными языками) упрощает поддержку кода, и доп.синтаксис ФП языков тоже упрощает поддержку кода. Разница в том, какими методами это достигается. Как мы все знаем одна из основных философских предпосылках ООП это сокрытие внутреннего устройства объекта, что конкретно реализуется с помощью инкапсуляции. И все мы знаем, что сокрытие помогает. Оно помогает двумя вещами: во-первых на приватный api не распространяются гарантии для пользователей -- что важный социальный фактор, во-вторых оно дает гарантии разработчику на согласованность сокрытых элементов. Первый пункт на самом деле очень важный и я честно не подумал о нем, когда писал свой комментарий выше -- думаю тут без сокрытия никак не обойтись. А вот второй пункт можно обойти. Дело в том, что гарантии на согласованность это на самом деле гарантии, что никто из вне не придет и не запишет свои странные значения, когда этого нельзя делать. Т.е. на самом деле это защита от записи. Ну и ФП языки решают эту задачу куда элегантнее. Что касается огромных проектов: есть большие распределенные системы на Erlang, например. Ну и на самом деле это конечно миф, что на ФП языках никто не пишет ничего, есть много интересных проектов и на том же хаскели и на F#. Короче мое мнение такое, что в столкновении "ограничение видимости" (как принято в ООП) vs "ограничение прав записи" (как принято в ФП), побеждает второе. Это основная тема доклада и поэтому я считаю, что Егору больше понравятся ФП языки т.к. по моему та проблема, которая его больше всего заботит, там решена лучше.
у меня два существенных пункта -- и потому я их оформлю двумя отдельными комментариями. вот за счет чего ООП упрощает поддержку кода по сравнению с процедурным программированием? аналогия: за счет чего происходит развитие науки? за счёт того, что некоторые сущности, которые прошлое поколение воспринимает сложными, комплексными, новое поколение считает простыми, атомарными. не как пачку объектов/свойств, а как один объект. например, матрицы. сложно оперировать понятиями матриц, если постоянно воспринимать каждую как таблицу чисел. сложно представить себе как выглядит произведение матрицы на обратную -- если представлять её как прямоугольную таблицу чисел. но очень просто -- если воспринимать матрицу как атомарный, неделимый объект со свойствами (хотя, конечно, мы помним, что матрица -- таблица чисел). соотвественно, упрощение ООП по сравнению с процедурным программированием -- за счёт того, что у нас всё более крупные и сложные вещи используются как простые, атомарные. и когда мне надо отправить команду на ЮСБ-девайс -- я просто беру объект "девайс" и говорю "вот тебе команда". и мне не надо представлять весь объем логики, за этим скрывающийся. мне не надо помнить, как там управляются потоки, как команда преобразуется в массив байтов, как это скармливается библиотеке вместе с точными координатами отправки, как оно скармливается ядру, как передаётся именно этот тип пакетов, как работает синхронизация итд. и сокрытие -- это всего лишь способ сделать простой, атомарный объект из огромного комплекса свойств. так вот, соответственно, вопрос. каким образом ФП делает программирование более удобным? за счёт чего? (на всякий случай -- речь идёт не о сокрытии -- ведь сокрытие -- это всего лишь средство, способ добиться того, что написано выше).
2. вы пишите "сокрытие помогает 2 вещами". да. но не теми, что вы описали. 1. самое главное в сокрытии -- это не то, что скрыто. самое главное в сокрытии -- это то, что открыто. Интерфейсы, контракты -- всё это. сокрытие позволяет нам менять части кода -- и быть уверенными, что это не испортит ничего вне определенного scope. именно сокрытие позволяет сделать "разделяй и властвуй". именно сокрытие позволяет абстрагироваться от реализации. и вершина сокрытия -- это не private. и не отказ от сеттеров. вершина сокрытия -- это интерфейсы. когда объект умеет выполнять определенные задачи -- и всё остальное никого вне объекта не касается. и именно это ("реализация -- вас не касается") -- сделало ООП настолько удобным для больших проектов. и по поводу ведения больших проектов на ФП. я совершенно уверен, что существуют люди, которые в состоянии вести большой проект на процедурном языке. делать это правильно, корректно. так, что код не становится безобразной кучей, к которой противно прикасаться. и такие проекты -- есть. например, написанные на чистом С. до сих пор живут и здравствуют. но это ведь не говорит нам о том, что поддерживать процедурный проект так же просто, как объектный? таки чем ФП делает поддержку проекта более удобной, чем ООП?
1. Ещё раз. ФП делает тоже самое, но по другому: там другие абстракции, но они служат той же цели. Здесь изобрести другой цели нельзя, все мы хотим одного и того же. Если вы не знаете какие специфические абстракции есть в ФП языках и хотите, что бы я вам тут в комментариях на ютубе всё рассказал, то этого не будет :-) 2. Тут у вас какая-то каша с моей точки зрения, может я вас не так понял, но давайте по порядку. 2.1 Сокрытие очень простой термин, работающий бинарно -- либо открыто, либо закрыто. Говорить, что в сокрытии главное открытие это как говорить, что в boolean важнее всего true, а не false. Толи я вас не понял, то ли вы сказали что-то странное. Если бы в бинарном понятие самой важной была бы одна грань, тогда можно было эту одну грань оставить и само понятие ликвидировать, т.е. "сокрытие нужно, что бы кто-то другой мне тут не накуролесил" это тоже самое, что сказать "сокрытие нужно, что бы открыть в правильных местах, где можно безопасно куролесить". 2.2. Интерфейсы это совсем из другой области. Это из области контрактов и системы типов. Они везде тоже есть. В ФП языках обычно очень богатые системы типов. Эта задача в общем-то везде решается достаточно хорошо, хотя мне не хватает алгебраических типов данных в джаве, но я не могу сказать, что прямо страдаю без трейтов например. Ну т.е. имхо это важная вещь, но она везде решается достаточно хорошо, что в результате нет особой разницы. Но если вас богатые системы типов делают счастливее, то вам тоже понравятся ФП языки, больше чем ООП. 2.3. Ну да, есть Linux, PostgreSQL, проекты написанные на ванильном Си. Мы все их знаем и любим. Я не знают, что это говорит нам, подозреваю, что организация процесса важнее выбора языка. Или что-то в этом духе. 2.4. Я не говорю что ФП делает поддержку удобнее, чем ООП. Я говорю, что в той отдельно взятой вещи, к которой Егор прицепился, подход ФП языков лучше, чем подход ООП языков. Поможет ли это сделать проекты лучше я не знаю. Я говорю, что считаю, что отдельно взятый Егор станет счастливее если перейдет на ФП язык.
видимо не знает тип что геттеры создавались не как способы доступа а как декоратор (т.е. в теории поле может быть не стрингой а массивом чаров), и то что он переименовал геттер в контент сути не меняет.почти час болтовни ниочем.
Dmitry Egorov Суть не в гетерах, основной посыл был, что данные должны обрабатываться внутри объекта, а не передаваться в неизменном виде от объекта к объекту, используя поле как хранилище данных.
Не согласен с Вашим отношением к Null На мой взгляд Null - величайшее изобретение, если Вы правильно понимаете суть. Null -это НЕЧТО, Потенциальная возможность реализации чего-либо, в то время как Ноль это НИЧТО, Пустое место Если помните Творец Создал НЕЧТО из НИЧЕГО То есть - Ноль это - Я Знаю что здесь пусто, а Null - Я Не знаю что здесь, пусто или нет, мне неизвестно. Как можно использовать в жизни: допустим Вам необходимо регулярно делать записи в таблицу, где есть обязательные параметры, например дата и текстовая запись, и ряд параметров классифицирующих и уточняющих эту запись. И эти параметры вы можете заполнять сразу если время позволяет, либо когда оно появится. Вот Вы открываете начатую запись и пытаетесь вспомнить, я в этом поле специально ноль или пустое место оставил, или я его ещё не заполнял? Это ведёт к лишним расходам Вашей психической энергии. А когда есть Null всё однозначно, значит это поле я ещё не заполнял, а нсли здесь ноль или пустая строка, то это было мной сделано намеренно. Не Важно, Прочерк.
похоже, спикер считает процедурнре и императивное программирование синонимами. процедурное - это всего лишь способ структурирования императивной программы. ровно как и объектно-ориентированное.
В общем-то, всё правильно говорит о сферическом ООП в вакууме, но на практике эта идеальная сферичность мало нужна. В т.ч. и для сопровождаемости. Там кто-то из комментаторов упоминал SmallTalk, он как раз не взлетел исключительно из технических соображений - уж больно медленны были программы на нём в то время. А теперь поздно, да и не нужно, всякие CORBA, DOLE, PDO и прочие «умные объекты» тоже не особо-то взлетели, как и ActiveRecord - основной источник проблем с производительностью и масштабируемостью в Рельсах, AFAIK.
Такая себе критика, особенно про статические классы. Код нужно организовывать, если понятие Class использовать как некий namespace то че париться, надо просто правильно обозначать сам класс. Чтобы компилятор не ломал себе голову созданием конструктора/деструктора.
Мне кажется везде должен быть баланс. И очень много маленьких классов это не гуд, и гигантские супер классы тоже явно это плохо. Должен быть какой то разумный компромис между размером класса и количеством классов.
И в шарпе вагон объектов-значений:struct,record class,record struct. Record class каешн ссылочный тип,но суть вродь та ж. Вместо изменения состояния и велосипедирования кода для порождения из текущего объекта нового с измененными значениями юзается один и тот же вшитый метод.
Автор прав в большинстве своем. Только геттеры нужны исключительно в тех случаях, когда возвращаются данные, которым не нужна логика по типу user.getName(), плохим тоно было бы делать методы user.getRole(), т.к. это провоцирует пользователей класса писать логику, относящуюся к классу, писать вне класса - а это усложняет поддержку проекта и реально нарушает инкапсуляцию. Статические методы нужны только для тех классов, поведение которых мы не можем изменить, это системные классы по типу List, Set, String. Но автор не прав в ответе на первый вопрос из аудитории. SRP звучит как "у класса должна быть только одна причина для изменения". И в такой формулировке мы можем спокойно все утилитные методы поместить в один класс и это будет нормально поддерживаемо, уж лучше чем огромный набор утилитных методов.
Ооп ради ооп. А Профит то где? Поддерживать сложнее, разрабатывать сложнее. Кало-кода ещё больше будет, если следовать подходу автора. Теперь вместо одного сервисного класса заведем два десятка фасадов.
ООП это как конструктор лего, где детали либо похожи либо одинаковы. Много для чего подойдет. Но для реального творчества и произведений IT искусства нужна глина тонкого помола с мельчайшими частицами, а не конструктор. Но для очень крупных проектов конструктор лего будет той самой глиной, потому как размеры проекта этом случае гигантские. Вот и все что нужно знать про ООП. Если проект небольшой, содержит 10 функций, то никакого смысла вообще в классах нет.
@@KKZ_5000_RUB вы говорите не об ооп, а о библиотеках, модулях, классах и интерфейсах. но это не ооп а способы структуризации кода, используемые во всех парадигмах. ооп это всего лишь методы, которые могут хранить состояния, или состояния с определенным поведением. всё остальное (включая классы и интерфейсы) - это только полки, на которые можно разложить эти методы, и к сути ооп не относится.
ООП - это просто один из способов связать данные с кодом, который завязан на эти данные. И всё. Ничего лишнего. Причем в разных языках эта идея реализована разными способами, со своими особенностями и костылями Например в одних языках есть структуры данных и процедуры. Хочешь поменять структуру - вызови процедуру и передай в нее структуру: doSome(struct, data) В других языках решили организовать это в виде ООП, но не переусложнять, и появились составные классы, появилось понятие контекста, this. Процедуры теперь сгруппированы по неймспейсам, по классам, но это все ещё старые-добрые процедуры, и чтобы изменить в них структуру, ее туда нужно явно передать, в аргументе, написать код вида class.doSome(object, data) А сами структуры, чтобы связать их с классом, стали складывать в анонимные переменные, которые маппят под капотом на какую-нибудь заранее определённую переменную, такую как this или self. И вот мы уже имеем внутри класса странного вида вызовы, типа class.doSome(self, data), чтобы связать процедуры с контекстом, со структурой данных, которая содержит состояние объекта Ну а в третьих языках решили сдобрить все это синтаксическим сахаром, и спрятали this и self под капотом. При этом под капотом там все также отдельно структуры данных, отвечающие за состояние объекта, и отдельно структура данных, отвечающая за группировку процедур по классам, и в эти процедуры все также передается этот самый self, только теперь это происходит неявно, под капотом, и увидеть это можно лишь разбирая низкоуровневый код, который и работает под капотом языка и сокрыт за всем этим синтаксическим сахаром. И вот у нас появились вызовы вида object.doSome() И по итогу получается что у нас есть процедурный подход, и есть несколько реализаций ООП подхода, но по факту все это оказывается одно и тоже, просто в одном случае все это работает явно, а в другом неявно И выходит спорят люди просто из-за разницы в способе организации хранения процедур: в одном случае их хранят с обязательной группировкой по отдельным файлам, а в другом - с необязательной 😂
Почему ноль ответственности? Ответственности ноль - это когда вы просто пишете говнокод и аргументируете это тем что это поддерживать придется дальше кому-то другому. Когда вы правильно используете инструементы, которые вам предоставлены, то это не "ноль ответственности". Работу надо делать хорошо всегда
нет, он относится к инструменту как к инструменту, другое дело, что ему очень нравится этим инструментом работать. такие специалисты мне самому нравятся.
Краткое резюме. Раньше существовали процедурные гитары, вы двигали руками и пальцами и думали как гитара и всю ответственность за производимую музыку брали на себя. А ООП гитара это новый шаг и новое мышлнгие - нажимаешь кнопку сыграй "звезду по имени солнце" и гитара сама играет. Ваши пальцы не могут нарушить инкапсуляцию и вмешаться в производимую мелодию. Вопрос из аудитории. А если я хочу сыграть "дождь идет с утра"? Ответ - тогда вы создаете новый класс, который ответственен только за игру "дождь идет с утра".
Если у нас уже есть класс, который умеет проигрывать музыку (например: "звезду"), то зачем нам ещё один класс для проигрывания "дождя" ? С технической точки зрения, песня "дождь" ничем принципиально не отличается от "звезды", это просто разные комбинации аккордов. В чем смысл создания ещё одного проигрывателя?
ну вы мыслите слишком узколобо, вы говорите о гитареИграющейЗвездуПоИмениСолнце, но гитара имеет метод сыграть мелодию, получает на вход мелодию и играет ее, а уже мелодия является такой-какой мы ее создать хотим хоть "звезда", хоть "дождь", хоть "сигареты"
Ушел переписывать сортировку пузырьком на ООП. Выделил объект пузырек. обернул в объект сортировка. Дальше запутался, помогите!
Ну изи же - пузырек нужно было обернуть в декоратор "ComparableПузырь" потом накидать эти пузырьки в список, а для списка сделать декоратор "SortedList"
Но сортировка же не объект, а функция
Создаешь класс Value, в нем 2 метода equal и greater, которые принимают на вход другой объект класса Value. Создаешь класс Sorter с методом sort, который проходит по обектам и сранивает их и возвращает отсортированный список. На самом деле слова докладчика верны и на таком принципе работает react js, но он заехал не на ту конференцию и выбрал не тот язык, в котором его концепция реализована. Ему прямая дорого в ФП, а именно в хаскель или immutable.js
@@DanilaAvdoshin вот про это и говорят в видосе. Думаете не объектами, поэтому и не сходится. Про функторы ака функциональные объекты не слышали?
Я понимаю что это ирония, но для тех кто не вьехал:
Что за объект "сортировка"? Объекты называются не по принципу "что он делает", а "чем он является". Объект не может являться "сортировкой". "Пузырьком" тоже.
У вас есть объект "какие-то данные", делается декоратор "отсортированные какие-то данные", у которого сортировка происходит в конструкторе (насчёт этого не совсем уверен, кажется это не совсем соответствует идеологии Егора, но хрен с ним, суть не в этом). Вы инстанцируете "отсортированное", скармливая его конструктору уже существующее "неотсортированное", у вас получается объект, содержащий отсортированное.
Только не надо просить от меня объяснить почему якобы я считаю что всё это правильно, я ничего не считаю, а просто передаю вам мысль оратора как её понял я.
Борьба за права объектов.
А классов?
Докладчик пытается изо всех сил притворяться, что данных не существует, и пытаться писать программу так, будто есть только поведение, а данных нет. Именно поэтому сферическое ООП в вакууме, которое он проповедует, так и не вылезло из песочницы, ведь за её пределами данные и способы работы с ними игнорировать невозможно, а в распределённых системах они и вовсе выходят на самый первый план. Способы разбиения данных, компромиссы CAP, как мы будем разруливать неизбежные конфликты и partial failures - вот о чём болит (или должна болеть) голова у стоящих разрабов. А не о том как пообъектнее изобразить живой объект комментарий который умеет себя редактировать. Тьфу.
вы путаете архитектуру и реализацию. В вашем примере "стоящие разрабы" должны заниматься написанием алгоритма, а в видео речь об архитектуре проекта, которая неизбежно скатывается в уг из-за непонимания, как вообще ее строить. Тьфу (с)
partial - антипаттерн
@@acd2377 да, конечно же мы можем измерить габариты табуретки. Вопрос геттеров больше философско-концептуальный, чем имеющий практичное значение. Вреда от геттеров немного, но обычно они указывают на "код-смелл". Вам вдруг зачем-то понадобились параметры табуретки вместо того, чтоб взять и сесть на неё. Потому что объект табуретка создается для того, чтобы на нем сидеть. А если вам нужны габариты табуретки -- то вам стоит спросить их у объекта "столяр", который построил табуретку и знает её структуру. А не у самой табуретки. В общем, если вы разговариваете с табуреткой -- в вашей жизни и вашем коде, что то определенно идёт не туда.
Вот как бы вкратце о геттерах, но повторюсь, что все эти принципы не могут быть строго формализированы и просто следует воспринимать как указания. Есть где-то геттер -- посмотреть, а действительно ли он нужен, и зачем внешнему объекту понадобились внутренние данные другого объекта, возможно внешний объект делает работу, которую должен делать не он, а запрашиваемый объект.
С сеттерами все сложнее и интереснее. Да, как бы это дико не звучало -- нужно выбросить старую табуретку и купить новую с другим цветом. Представьте себе, что табуретки в магазине по три на рубль, и для вас это финансово вообще не проблема. Но логичный вопрос - - почему нельзя перекрасить? И тут уже надо понимать почему у Егора текут слюни на иммутабельные объекты. А все потому, что они очень удобны и надёжные. В примере с табуреткой -- у вас есть табуретка черного цвета и в любой момент времени, разбуди вас в три часа ночи в воскресенье под дулом пистолета и спроси какой цвет у табуретки -- вы без тени сомнения ответите что чёрный. И будете правы на 100% и всегда, и во веки веков, аминь!
Чего нельзя сказать о мутабельной табуретке с сеттерами. Вы никогда не знаете, а не покрасил ли её сосед, пока вас дома не было. Вы приходите домой, ничего не подозревая, с разгону садитесь на свежепокрашенную табуретку и у вас вся ж...э-м-м.. седалищная часть брюк теперь ярко красного цвета. Вот чем плохи мутабельные объекты. Вы никогда не уверены в них на 100% и должны проверять "иф (табуретка не крашена") { сесть на таберутку } елзе { ждать пока высохнет краска }.
@@acd2377 "Модель мира" и "доминация" это лишь для красного словца. В действительности неудачные аналогии только вносят дополнительную неразбериху. Я просто отсеиваю их сразу и рассматриваю только практическую сторону вопроса -- чем мне это облегчит жизнь как программисту. Геттеры и сеттеры плохи именно с практической точки зрения. (Хотя это и странно выглядит поначалу.) А вся философия - это шелуха.
@@acd2377 Понятие "модель объекта реального мира" означает упрощенный вариант - имитацию некоторых свойств объекта реального мира. Думаю суть иммутабельных объектов в моделировании только нужных свойств, избавлении от ненужных состояний и лишней сложности из-за этого (Сложность от бесконечного числа классов, видимо, не учитываем). Получается при инстанцировании объекта табуретки мы создаем спроектированную в классе модель табуретки из реального мира. И этих моделей можно создавать сколько угодно с любыми свойствами в любой момент времени. Это наша виртуальная модель любой табуретки из любой точки пространства-времени реального мира. Например, увидели вы табуретку голубого цвета - у вас в сознании создалась модель иммутабельной голубой табуретки, затем вы посмотрели на табуретку желтого цвета - аналогично и с ней.
Вероятно видео должно было называться: ООП - Объектно-Ориентированый Пиздеж
По сути он предлагает процедурное программирование на манер ООП. То, что раньше было статическими функциями, теперь оборачиваем классами и гордо называем ООП.
ядрена мать! эту лекцию можно спроецировать не только на программирование!
забавно, чувак спрашивает у слушателей, знают ли они что такое геттеры, но не сомневается что они занют, что такое инкапсуляция)
Nik Pol гетеры в явном виде есть не везде.
Судя по-всему, он и сам особо не вьезжает в принципы ООП вообще и инкапсуляции в частности. Все рассмотренные случаи на слайдах - говнокод и он не постиг Дзена. Хотя как примеры, как делать не стоит (плодить классы ради классов и оба! - ты в ООП) вполне годно
@@miheiheld4458 К счастью..
Он сам перепутал инкапсуляцию и сокрытие
Егор здесь сам на себя не похож. Когда он спокоен, то рассказывает невероятно круто!
Как отказаться от статических методов, когда есть public static void main?)
public stativ void main final abstract anonimus function(){}
@@kek2961 убить мало за такое
есть целый static класс Math. а давайте теперь сделаем синусы-косинусы методами на дабле!
на самом деле он концептуально это метод приложения. Т.е. запуская приложение ты запускаешь метод маин, который подразумевает наличие своего приложения. Ты же не вызываешь main в коде?. Вообще его можно вызвать?. Т.е. если хочется поржать только, то можно шуточек найти, когда люди стараются сложную тему донести
@@megasuperlexa2 Синглетоны вам в помощь!
Класс 2dvector, его используют другие объекты, некоторые используют его координаты раздельно для проверки каких-либо условий. Получается для каждого использования я должен генерить новый класс потомок, инкапсулирующий работу с этими координатами. В пределе по доп.классу для каждого использующего класса. Это уйма лишней работы, а обозримость и анализируемом то кода падает до нуля - я должен елозить по огромному дереву на каждый чих, чтобы понять, что происходит. Безумно.
Почему getters и setters это плохо? Почему извне мы можем делать всё что угодно с этими данными? Отнюдь нет. С данными делать можно только в рамках дозволенного функцией. Например у нас есть функция set с параметром int. В неё можно поместить число в диапазоне 0..255, а мы поместили -15 или 300. Нам не нужно прописывать отдельные случаи с такими данными, функция set это уже реализовала.
В SFML есть класс sf::Text, в нём есть функция setColor. Через setters тексту нельзя применять цвет? Как иначе тогда?
36:14 У нас есть 2 варианта: файл переименовывается в той же папке или по новому пути. В чём принципиальная разница между методами Rename() и setName() если тело обоих методов одинаковое, разница только в трёх буквах.
Не являюсь сторонником выступающего, но что касается сеттеров, то с некоторыми оговорками он прав: любое изменяемое состояние (класса) ведёт к проблемам, особенно в многопоточном окружении. Ибо его надо синхронизировать. А любая ошибка при реализации синхронизации приводит к трудно воспроизводимым и исправимым багам. И даже правильная реализация может приводить к частым блокировкам потоков и потере производительности. Кроме того, и вне многопоточки код с отсутствием изменяемого состояния гораздо проще читается и воспринимается. Если вы хотите изменить состояние объекта, то, как автор и сказал, просто создаёте новый на его место. В этом случае ваша функция setColor вернёт новый sf::Text - дубль старого, но с изменённым цветом. Так это работает в ФП во всяком случае.
@@zachemny По поводу setColor и sf::Text. Я увлекаюсь кибербиологией, эволюционным моделированием, там каждая секунда на счету. Если заново создавать sf:Text с его атрибутами (цвет, шрифт, размер, атрибуты стиля, толщина, цвет контура шрифта, позиция на экране и т.д.) всё это отдельные функции и при каждом создании нового текста ради цвета придётся вызвать 8 функций. Я подозреваю каждый вход в функцию, если она не inline кушает ресурс процессора. Способ который предлагаете вы, возможно более читабелен, но боюсь медленней чем тот, который использую я (ради цвета вызываю только setColor()).
@@UFO26 Ну, я не пытаюсь навязать вам данный подход. В каждом конкретном случае он может оказаться неудобен или даже неприменим. Хотя выглядит несколько странно, если у вас моделирование привязано к изменению или выводу текста, обычно эти задачи разносят, и там, где идут хардкорные вычисления, текст не генерируется. Хотя, возможно, я что-то неправильно понял.
8 функций для создания объекта вызывать по идее не нужно, вызывается клонирование предыдущего объекта с изменением его свойства. Но поскольку иммутабелен весь текст, то клонирование придётся повторить для всей предыдущей части части составного объекта (графа объектов).
Вообще же иммутабельный подход к структурам данным считается более медленным, зато приводит к упрощению кода (особенно многопоточного). Ускорение тут достигается засчёт более эффективного распараллеливания. Ради каждого изменения приходится изменять почти весь граф объектов (начиная с корня до тек. узла, т.к. они все иммутабельны). Но, в то же время, это можно делать в отдельном потоке, что может в итоге оказаться даже эффективнее, чем блокировать весь граф для др. потоков на время внесения изменений. Привнесение изменяемости для классов в этом контексте считается оптимизацией и выполняется только тогда, когда все остальные средства уже исчерпаны, а скорости всё ещё не хватает.
@@zachemny спасибо за развёрнутый ответ.
@zachemny, хм, учитывая то что вы описали как фп, предметно ориентированное выходит синтезом фп и ооп.забавно. объекты-значения как раз таки immutable
Этот ролик нужно промаркировать "45+" )))
обьект file не должен иметь геттер, который мог бы вернуть path. А как тогда реализовывать его же декоратор (не знаю, почему сабж использует этот термин)? вот хочу реализовать mmap, или типа того же file input stream, или random access file? в конечном счете все равно придется получить path, что и сделали в JDK
А зачем вам в декораторе path?
Дистиллированное ООП не стоит делать самоцелью. Институты одобряют. Индустрии важнее практичность. Элементы ООП могут удачно уживаться в одном проекте с элементами не-ООП. Если ООП в реале так часто протекает, значит дороговато все-же его ТО? Выход из ограничений ООП - это не всегда плохо, а иногда даже очень даже удобно.
@Белояръ Чайка Чем помойка статик методов хуже помойки классов :)
@@inbuckswetrust7357 ну тогда не понятно, а зачем статик метод пихать в класс, состояние объекта которого он не использует? Почему это не может быть просто отдельная функция? Зачем плодить сущности, если смысл тот же?
На мой взгляд, помойка классов хуже помойки функций. Потому что из функций мы составляем алгоритмы. Все предельно ясно. А классы могут (и обязательно будут) находиться в очень сложных отношениях между собой, из которой логику работы сложно понять.
@@vanyasotnikoff6024 помойка объектов и тем более абстракций - тот еще адец.
@@grace-pt4hwпотому что имя класса, в котором объявлена эта функция даёт дополнительный контекст читателю кода - это раз.
Куда ты предлагаешь засунуть эту функцию, если не в класс? Физически где ты собираешься писать ее? Это два.
"Неужели нельзя посреди кода в объект вписать какое- то число, которое вдруг показалось важным? Это же мой любимый паттерн погромиста!"
Как подобные товарищи будут реализовывать многопоточность на уровне задач (а не данных), которая реализуется через асинхронное выполнение (а значит нет последовательного кода, следящего чтобы все было согласованно)? Да не писали они никогда ничего серьезного, вот и воют, что у них забирают возможность писать код- лапшу.
у автора много видео с "критическим" мышлением, как по мне обычный самопиар
и мне люто интересно, где же он там в spring увидел кучу геттеров? это вообще то штука о DI с бинами на секундочку. я о том, что мне кроме POJO , нигде там геттеры и не нужны особо были.
@Белояръ Чайка Забавно, как те, кто его поддерживает, не знают даже языка, на котором излагают мысли. Не говоря уже о Java.
Из лекции взбодрило "моя книга стоит 41$"
$41
Интересно взглянуть на код докладчика
посмотреть бы на код калькулятора в стиле ООП с такими вводными
Да, это жёстко
var sum = new SumOperator(value1, value2);
sum.GetResult();
Не сложно, покуда вам пофиг на фрагментацию кучи.
c=a+b
a и b - экземпляры класса вводных данных. c - экземпляр класса суммы.
На каждой операции создаём и удаляем объекты в куче.
Вместо тривиальной перегрузки сложения надо написать по классу на каждый вариант расстановки типов данных по слотам вывода и параметров перегруженной функции.
И создать по уникальному имени для каждого класса.
...
А потом кто-нибудь изобретёт перегрузку для имён классов.
Егор, отличная лекция о "философии на пальцах", продолжайте в том же духе! И разработчики java не смогут игнорировать такую статистику, и улучшат её))
От написания кода на таком двинутом ооп страдает оптимизация и едва ли его сильно проще подлерживать в масштабе больших проектов
П.с. досмотрел до вопросов и понял что я бы очень долго спорил с этим докладчиком
П.с. сколько в параметров у типичного персонажа или предмета в игре? Конечно тут есть наследование, но на выхлопе разобратся в коде пусть из маленьких но 100 000 классов, будет нифига не проще. Например шлем, классы предмет>броня>клас ксотюма>шлем в конечном объекте нам надо хранить данные на удары по какой части тела он действует, заерывает ли он лицо, сопротивление к разным типам атак, и это может быть ещё тонна параметров и на выходе не всегда получится разбить всё до уровня 4-5 публичных методов, и опять же ююигроку на экран в инвентаре по хорошемы нужно вывести какието параметры этого шлема, и других айтемов в его инвентаре и т.д. почему не сделать гетер? Просто гетер и не написать просто функцию которая соберёт данные со всех надетых айтемов брони для того чтобы выводить эти данные, надо дёргать отделбный метод, который будет помимо зюсвоего объекта ходить в таблицу и отдавать туда свои параметры? Так чтоле?
Я не претендую на гуру геймдева, я просто не понимаю людей которые несут подобное и прямо таки жаждут писать на чистом ООП, и опять же, пусть даже мы будем максимально дробить классы, они требуют больше ресусорсов платформы для исполнения проги, функции или статические методы могут работать быстрее уже просто на выхлопе компилятора со стандартными настройками, а про ручную оптимизацию этого выхлопа и настроек компилятора я уже промолчу.
по игору пересоздай шлем на каждом ударе, а лучше три раза, будет моргать на персе но зато швятое ооп по игору
@@denisviklov4596 Не, там на каждый фрейм придётся пересоздавать всех персонажей и часть ландшафта вроде деревьев и травы, ведь они каждый фрейм меняют своё состояние))
Докладчику нужно не код писать, а IDE блочное, как в Unreal Engine 5, где компилятор уже сам все эту структуру оптимизирует в нормальный машинный код)
За смелость мысли лайк. По поводу объекта согласен
Не знаю по мне слишком заморочено, есть люди которые едят только мясо, они говорят есть овощи не правильно вовсе.
Есть и другие психи кто одну траву жрет и приводит 100500 пруфов что так правильно жить.
Но истина посередине, плодить миллиарды микроклассов это утопия, но и создавая объекты надо думать надо ли пихать везде сеттеры, и думать о доступе, так же использовать оптимальные функции для экономии ресурсов железа, и тд, не надо кидаться в крайности, если вам дали много инструментов это не значит что есть суп надо вилкой, держа её пинцетом зажатым в левой ноздре.
Ненадо создавать статические методы, создавайте маленькие классы для каждой функции, окай джениус детектед.
мнение что класс - это просто набор методов и свойств ведёт нас обратно в язык С... а понимание что класс - это живое существо ведёт нас далеко вперёд.... в 41 тысячелетие. тонко
Доклад очень интересный, но несколько раз был задан хороший вопрос , а как эта концепция сказывается на производительности. Не на пустом же месте появились move семантика и cow. Помню в одном из проектов после профилирования, обработка строк занимала 80% машинного времени.
37:12 - аналогия класса String, любое присвоение переменной нового значения пересоздает объект. в принципе логично. ведь файл новый. значит и объект новый.
Непонятно в чем разница то, ну не хочешь большой список иметь простых методов, будешь иметь херову тучу своих микроклассов :) типа супергибко но ужасно неудобно пользовать это все.
Белояръ Чайка не микроклассы это когда из надувных уток строишь авианосец ;) утки должны быть заменяемы на гусей ;)
Значит вам дорога в функциональное программирование.
Так классы нужны для того, чтобы объединять объекты, которые будут иметь схожие характеристики и схожее поведение. Если объекты будут без привязки к классам, тогда будет много дублирующегося кода. Разве не так?
это как в жаве можно объект создавать, не указываю его тип)
Нет, классы для этого совершенно не обязательны. Иначе процедурное или функциональное программирование не могли бы существовать в принципе. Помимо наследования через классы существует прототипное наследование в js, а самое главное, существует такое явление как "композиция".
По моему опыту: схожие объекты объединяются классом без логики и всеми публичными полями, либо стуктурой. После этого создаются классы-конвеер которые эти объекты обрабатывают. Но это не ООП. Происходит сепарация данных и логики, как это делается в функциональном программировании. Объектное же подразумевает инкапсуляцию логики и данных внутри одного класса.
Кручу верчу, книжку вам продать хочу! Со скидкой )
Причем смотреть доклад нужно ПОСЛЕ просчтения Effective Java.
Правда прибегут потом фанатики и свидетели быстрого С++ и расскажут как плохо пересоздавать объекты
Конечно не полностью согласен, но разумные мысли есть. И зря его все здесь так поливают. Именно так и должно идти развитие, путем анализа и отсечения полезных или не полезных идей.
Идеи понятные, интересные. Столпы ООП (типа Гради Буча) вобщем-то и учат изначально такому мышлению. Однако потом наступает реальный мир, где вместе пятидесяти классов тупо проще сделать один и допустить, что в нём часть свойств могу быть null. Тчк. И когда тебе твой бизнес-манагер стучить по голове со словами "когда будет сделано?" по 10 раз в день, ты рано или поздно будешь всё чаще и чаще выбирать менее time consuming вариант. Так работает практика. За очень редким исключением, когда какие-то решения могу быть проработаны наперёд и ясно, что они дают некую гибкость на будущее и позволят в будущем сэкономить labor cost. Однако это тоже зачастую нивелируется реальной ситуацией, где есть масса проектов, которые толи проживут ещё месяц, толи нет. И далеко не всегда в реальном мире прям нужно заморачиваться с правильностью ООП.
Ну и наплодил ты кучу классов - вернулся к куче процедур на Cи.
имхо - суть и смысл этого доклада улавливается быстро и понятно, но нельзя возводить в абсолют такие вот "методологии" разработки, потому что в дальнейшем расширять проектный функционал будет практически невозможно, потому что (если я
правильно понимаю) код начнет расти в геометрической прогрессии, а вместо "ненужных" поджей появятся "столь необходимые правильные объекты"... но если поджу можно просто дополнить, то те самые правильные объекты нужно будет экстендить... то есть проект перестанет быть компактным по самой структуре... короч это опять палка о двух концах. искать золотую серидину опять придется каждому самостоятельно.
я вообще не программист, а ядерный физик с образованием математика, но спрошу:) Чем микроклассы по сути отличаются от обычных процедурных функций типа того же fopen? это не отход ли от ООП? И чем декораторы с новыми методами отличаются от классов, наследующих примитивный класс File?
декоратором ты же оборачиваешь функции или методы классы и даешь им новое стандартное поведение, можешь думать о них как о pre-hooks, дюже удобная штука, про класс вообще не понял к декораторам отношения не имеет
Возникли те же вопросы...
Ничем кроме покупки книги этого товарища)
Есть такая поговорка - если у человека есть лишь молоток, он везде будет видеть гвозди.
"НЕ используйте хибернейт и спринг в написании программ на джава"...
Мне действительно жаль себя и всех людей которые потратили время на просмотр этих фантазий на тему программирования.
5:06 Потому что, первое, объекты объектами, но в нормальном, не экспериментальном коде требуется оптимизация, а она с трудом возможна без процедурного подхода (без понимания процедур, тех процессов, которые стоят за всем). Недаром наиболее производительный софт писался и пишется на Си. В результате получается, программист должен мыслить одновременно и объектами, и процедурами. Второе, отсутствие нормального, единогласного, общепринятого, прозрачного объяснения основ. Нигде нормально не расскажут что такое инкапсуляция и полиморфизм, зачем они нужны в ООП, и почему ООП без них невозможно. Даже у апологетов противоречащее на сей счёт мнение. Касательно объектов, ООП это и то, что даёт инструменты программно описывать объекты, выделять участки кода, представляемые как объекты, и объектами является все в коде, любая буква. Это всё путает и грузит. Третье. Не только компьютер, и человек мыслит процедурно, особенно в том, что касается наук или каких-то навыков.
Да во всех букварях пишут вполне ясно и доступно, что такое инкапсуляция, и тп.
Амм,нет. Человек в наууах мыслит объектно с сохранением инвариантов бизнеса) матрица-объект,вектор-объект,алгебра -объект. Как то так.процедурно никакой науки нет.
31:17 это какой-то лютый пиздец, декоратор чтобы читать построчно, давно уже все придумали два разных метода, при этом делаем отдельными методами все для подготовки файла к чтению, потом тупо имплементируем прочитать все или прочитать и вернуть строку, в первом случае тупо будет определять границы файлы и возврощать строку, во втором по символ переноса строки и проверять что не выходим за границы файла на следующей итерации.
Вообще по уму для получения массива строк из массива байт нужна отдельная сучность-фильтр. Которая сможет работать не только с файлами.
в целом интересно, но не очень понятно как это применить в суровой реальности enterprise.
мне пока сложно представить, как можно этой концепции строго придерживаться на практике.
нам с фронта может прилететь большая котлета с частично заполненными полями, которых в принципе много. это все ифами и декораторами разруливать чтобы распихать по маленьким классам?
я думаю спринг, хибер и иже с ними были созданы не от того что их создатели процедурно мыслят, а как необходимое зло.
Если фронт способен пуляться такими котлетами, значит с самим фронтом что-то не так. Но в антрепризе да, куча легаси и совершенное отсутствие времени, средств и желания что-то переделывать. Кобол вам в руки, и будет полное антреприз-счастье, да.
то о чем он говорит для этого есть целая аббревиатура, не помню как называется, там этих парадигм и принципов туева хуча, господин Немчинский хорошо об этом расскажет
Интересный доклад. Было бы любопытно посмотреть код Егора, чтобы узнать насколько строго он сам придерживается названных правил, ведь это довольно непросто. Хотя по-моему верно для ООП. С другой стороны, в java добавлены элементы функционального программирования. Так нужно ли так строго соблюдать постулаты ООП ? Не лучше ли найти компромисс? В любом случае дана пища для раздумья.
Есть мнение,что ооп вобще придумывали ,чтоб побыстрому кучу программистов в рыночек вписать
"У нас появляются со временм много костылей, код сложно понимать, хочется его выбросить. По этому ООП это будущее!"
Звучит очень похоже на...
"У нас кривые руки, нам нужно 200 слоев абстракции ООП. Мы страдаем и вас заставим!"
дело в том, что мыслить можно как угодно, хоть объектами. Можно придумывать и "живые сущности")). Но в итоге все сведётся к обычному процедурному коду)
процессор к сожалению не "думает" объектами )
Да, это правда, но все эти концепции способствуют разным гарантиям в работоспособности этих инструкций)
Не поняла: какое такое "всё", и почему оно сведется к обычному процедурному коду?
@@princessmary5556 всё необходимо так или иначе транслировать в процедурный конвейеризированный код, которым является последовательность операций АЛУ процессора. Из-за этого все ограничения машинного кода будут унаследованы любым ЯП любой парадигмы любого самого высокого уровня, на котором пишет программист. Поэтому если среда выполнения не может транслировать высокоуровневый код в эффективный процедурный код, то код эффективным быть технически не сможет, какая бы моча философам в головы ни била.
Никто так и не вспомнил, что от immutable объектов GC начинает вешаться при хоть сколько-нибудь активной работе.
Зачем говорить, что "мыслить объектно" - это облегчение для программиста, если практика оказывается показывает, что для программиста естественно мыслить процедурами и программисты даже используя ООП все равно применяют процедурное мышление? Может надо перестать слепо верить в то, что объектно-ориентированный подход дает какие-то преимущества? И просто работать по улучшению методик и практик процедурного программирования?
Правильно. Писать надо так как проще. Так как мыслишь так и пиши. А не так как навязывают.
Я как-то класс какой-то заумный из 1000 строк на php переписал на процедурный в виде 5 функций обычных и понятных и в итоге код занял около 300 строк. Скорость выполнения специально измерил - она абсолютно аналогична. Читаемость кода значительно улучшилась.
И чего где какие преимущества? Просто крупные компании навязывают какие-то тенденции и все как дураки слепо идут в этом направлении.
@@KKZ_5000_RUB в итоге по сути ты последовал идее Егора, разбив большой умный объект на простые и от этого выиграл. Просто ко всему этому добавляется иммутабельность, которая порождает thread-safe, конечно, не все она надо, ну тут уж.
Ещё не досмотрел, но если из его понятия объекта просто убрать термин "живой", то получится абсолютно всё тоже самое, как он это для процедурных языков описывал. Какие-то словестные спекуляции без сути
Попробуйте пописать код в таком стиле и вы увидите как она из императивного превращается в декларативный. Термин "живой" придумал не Егор, это из книги Object Thinking.
Ну используйте слова: "самостоятельный", "наполненный своей волей", "реализующий свои желания"... Смысл в том, что к объекту надо относится как к самостоятельной личности.
@@ivanaaa6049 Смысл в том, что объект существует во времени и пространстве
@@avikuloff И как одно противоречит другому? Вы тоже существуете во времени и пространстве, но реализуете свою волю (например, в предыдущем комментарии попытались отстоять свою точку зрения).
@@ivanaaa6049 Когда говорят, что объект "живой" имеют ввиду, что он подобен объекту реального мира, то есть он существует во времени и пространстве, обладает состоянием и имеет поведение. Живой, самостоятельный - это все от лукавого. Объект может быть зависимым (подчиненным), говорить о воле и желаниях вовсе не приходится, я человек - у меня есть воля и я могу реализовывать свои желания, а кирпич не может, но от этого кирпич не перестает быть объектом.
А вот как код выглядит при наличии set-еров и get-еров: th-cam.com/video/Kr--dGJAui4/w-d-xo.html
Да, Сергей дело говорит.
Но это не значит, что сетеры и гетеры вообще не нужны, это значит что их использование не должно нарушать инкапсуляцию и вообще здравый смысл)
Design patterns это плохо, это не ООП. Чтобы не было больших объектов с кучей методов мы будем оборачивать объекты... А разве обертка не паттерн?
Все яд,все лекарство(с) к-классика.
Вроде что-то и не плохое говорит, но ответы на вопросы вконце порадовали. "А что сделать если я хочу переименовать файл, а у меня нет метода сетнейм" -
спрашивает один дилетант. "А сделай метод сетнейм, только назови его ринейм" - отвечает второй. Становится очень интересно, когда говорят что ООП должен отражать реальный мир, и при этом дают какие-то непонятные рекомендации, когда на том же примере с классом "файл" очевидно, что изменять, переименовывать, показывать путь этот класс вообще не должен, в реальном мире как правило менеджер файлов должен работать с файлами. Это как в реальном мире говорить автомобилю перекрасить себя в другой цвет самостоятельно, а не обратиться с такой просьбой к мастерам.
"изменять, переименовать" - это "ринейм" получается что и есть. "показывать" - это ложится на вызывающий код, который такой же инкапсулированный для внешнего мира
Python SmiSoft автомобиль, поменявший свой цвет - это уже другой автомобиль. Даже по документам. Think about it! И ещё, то что он СЕГОДНЯ синий никак не отменяет тот факт что ВЧЕРА он был красный.
@@megasuperlexa2 Это проблема возникает из-за того что бумажные документы до сих пор на руках у нас. Поэтому и автомобиль другой и человек другой человек когда меняет паспорт :) потому что так проще системам учета но не человеку :)
Егор говорит о простой вещи: декларативность. О том, что нужно отражать бизнес -логику в объектах, чтобы с кодом было проще работать. Поэтому между setName() и rename() огромная разница. Никому же не приходит в голову назвать этот метод changeStringTypeFieldValue().
Просто представьте, что вам пришлось понять, что делает программа только лишь читая стектрейс.
То, что выступающий считает "идеальным ООП" было реализовано в языке Smalltalk чёрти-когда, тогда же не прижилось и умерло. Следовало бы тогда сказать и про то, что объекты, по сути, должны посылать сообщения друг другу и сами решать, когда на них отвечать и отвечать ли вообще, и про контексты объектов, и ещё, и ещё...) Идея, конечно, интересная, но уже позно. ООП сформировано таким, каким его видел Н. Вирт (алгоритмы+данные в единой коробке). Перечисленные выступающим фреймворки - уже де-факто стандарты и завязаны на текущей реализации ООП в java (взять, хотя бы, IoC в Spring который привязан к геттерам и конструкторам). И от этого всего уже не отказаться.
z0r pwnd Да не прижился Smalltalk, только посмотрите как человек радуется кода, изобретает Smalltalk заново. А не прижился он, так люди просто не захотели думать по другому. Да и для того чтобы работать в стиле который излагается в лекции нужна ide или система на подобие Smalltalk систем разработки, но надо сказать что и они не идеальны, но разрабатывать в них одно удовольствие.
z0r pwnd Да еще кстати, все о чем так мечтает автор, появилось еще в далекие времена, еще в COBOLе :)
точно
потом лекаси код после таких говнокодеров вести...
чему он научит то .. новых говнокодеров
По правде говоря, Smalltalk так и не реализовал полноценную отправку сообщений (там это по сути сахарок над методами), в отличие от Erlang/Elixir. Поправьте, если я ошибаюсь
Ага, а если файл у нас в пару гигабайт, мы, наверное, хотим буферизованое чтение. И навернуть потом сверху «вернуть контент одной строкой». После чего вся концепция простого базового иммутабельного объекта рассыпается. Достаточно посмотреть на реализацию IO без прикрас, чтобы понять, что это не самые простые вещи.
Кроме того, мне непонятно, что в таком случае делать с классическими задачами, которые мутабельности требуют - например, percolation, где у тебя может быть на входе двух или трехмерный массив на мегабайт, в котором клеточки открываются, и с каждой клеточкой нужно чекать, соединились ли грани. Каждый раз генерить новую карту на мегабайт? Удачи с 10к изменений массива. Реализовывать STM отдельно по каждому поводу? Затрахаетесь. Объясните, умные люди?
А как без стат. методов использовать паттерн Синглтон?
Через другой объект. Который будет знать, сколько объектов текущего класса создано. Идея в том, чтобы поручить создание одного объекта другому.
Можно получить синглтон не применяя сам паттерн) ты просто инициализируешь его через спринг. без бреда про живые объекты мы прожить можем а без IoC нет)
В Spring сли надо ты вместо синглтона делаешь ему другой scope ('session' например) и он будет сущесвовать один но на время сессии юзера в веб приложении. т.е @Autowired MyService myService...и к нему уже обращаешься через переменную
@@NeptuneCasto вы описали ровно тоже о чем сказал Николай выше.
@@РусланСитников-у4м Ваше право так считать. Но это не значит что это одно и тоже. Ответ Николая больше предлагает написать свой ApplicationContext "Который будет знать, сколько объектов текущего класса создано"
@@NeptuneCasto да. Принцип тот же
В итоге никто и не пишет "настоящих ООП" программ. Может быть, это не очень хорошая идея? Зачем заставлять себя "мыслить объектами"? Ждет ли нас реальное просветление в конце этого пути? Может быть современное процедурное программирование на практике достаточно неплохо работает? В сочетании с элементами ФП и ООП почему этого недостаточно? Некоторые аспекты ООП наверное актуальны, но стоит ли все вращать вокруг этого? Есть ли доказательства того, что ООП это тот самый правильный, идеальный подход к дизайну приложений?
На каждый пример плохого ООП приложения ответ обычно в стиле No True Scotsman, а хороших примеров за пределами книг и нет. Многие новые ЯП, опять же, процедурно-функциональные с интерфейсами. Вообще, чистые парадигмы -- это сомнительно, и попахивает религией.
Про геймдев я и вовсе молчу, тут во всю Data Oriented Programming и Entity-Component-System, массивы и хендлы.
Согласен, я хоть и начинающий программист, сделал для себя вывод:
чистый подход про который говорит автор - это конечно бред. Вообще ООП - отражает наш реальный мир и он проще для понимания. Инкапсуляцию нужно делать самой сущности, которую представляет объект если это путь к файлу то он не должен меняться, ну а для каждой возможности объекта создавать декоратор - это абсурд.
ООП на практике - это прежде всего способ переиспользования кода.
Не пишет-то не пишет, но вот от количество багов в софте повсюду заставляет задуматься, а что же делать, чтобы их не было. Я попробовал подход Егора на практике и был сильно удивлен тем, насколько легче мне стало писать юнит-тесты, насколько более читаемым стал код и насколько надёжнее в целом стал мой код. Проектировать - да, сложнее, но всё остальное стало очень сильно легче.
>> Есть ли доказательства того, что ООП это тот самый правильный, идеальный подход к дизайну приложений?
Нету. Зато есть множество свидетельств обратного.
TH-cam Channel какой подход егора? Про иммутабильность он правильно рассуждает, и про нуллы - явно где-то прочитал. Но какой его подход? Ведь его нет. У него получается гора мелких классов с 1 методом, которые непонятно как использовать - про composition root он сказал только одно: это очень плохо )
Была такая присказка, что первый язык определяет все остальное. И тот, кто начинал с бэйсика считай инвалид. Вот собственно первый звоночек у меня был в самом начале речи. Потом оратор попытался давить авторитетом, что он вообще тут не первый день, не насрали. Это был второй звоночек. Третьим звонком, после которого я поставил видео на паузу и стал писать этот коммент, стали слова о том, что сначала все программы на ООП красивые, а дальше полная жопа.
И так, товарищ оратор, надеюсь прочитаете. Вы не осознаёте всю проблему, вы такой ведь не первый и не последний. Вы привыкли смотреть на все снизу вверх, детали реализации у вас во всем на первом месте, для вас ООП показался враньём только потому, что вы пытаетесь его применять для удовлетворения вашего обычного рабочего процесса, вы видите только сложность инструмента и простор для возможной ошибки. Большой опыт может не только разнообразить знания, но и наоборот сузить, закрепив какую-то одну идею, доведя ее до локально вашего пика, а все остальное может не только не развиваться, но и забыться. Это иллюстрация проблемы опыта 20 лет и опыта 1 год, но 20 раз. Программы с развитием и навешиванием на них реализаций требований всегда с течением времени скатываются в говно. Говно вообще можно на любом языке написать. Но как только человек начинает нормально вырубаться в ООП, код поддерживается лучше. И да, ООП скорее не о программировании, а об организации проекта и его ведении и архитектуре. Вот и все. Не с того ракурса смотрите, разнообразьте представление о мире, не разочаруетесь.
По-моему он именно об этом и говорил
Мужик молодец! Объектам надо отдавать всю задачу, относится к ним как если бы у них была свои желания и воля. Это похоже на фирму, где каждый сотрудник отстаивает интересы своего направления. Можно вспомнить поведение программ в фильме "Матрица"- именно так надо относится к объектам. При таком подходе программист просто выбирает наполнение программы этими самостоятельными сущностями.
Погромисты негодуют :)
Точно, пример с Матрицей вообще прекрасен, особенно после его анализа на канале "ЧБУ". Кто не смотрел очень рекомендую - "Морфеус - программа" называется
И тут мы приходим к функциональному программированию, где данные не меняются. ООП это натягивание концепций реального мира на программирование. Вот в реальном мире есть объект пациент, сегодня к него есть аппендикс, завтра нет. И что надо порождать новый объект?
ООП не занимается натягиванием концепций реального мира на программирования. Не выдумывайте чушь.
@@princessmary5556, конечно. ооп не занимается реальным миром вообще. ооп это всего лишь инструмент управления императивным кодом. и программистами императивного кода.
@@princessmary5556 Он не выдумывает, он повторяет азы любого учебника по ООП.
Не использую ООП вообще, никаких классов тоже не использую, а тупо функциями все всегда пишу. Интернет бизнес свой.
И у меня нормально. Есть две квартиры и машина. Путешествую еще часто.
Так что это все просто инструменты. Которыми можно пользоваться, а можно и не пользоваться. Не нужно думать, что знание ООП и умение мыслить как-то иначе что-то вам даст какие-то преимущества.
Самое главное пишите так как думаете, как вам удобнее. А все эти тенденции и модные тренды это пусть в гугле и фейсбуке там сами на своем ООП пишут. Мне оно даром не нужно. Кода больше получается, читаемость хуже. Понять код зачастую тоже сложнее. И зачем оно нужно такое?
Так же ка и стрелочные функции и всякие сокращения я тоже терпеть не могу. Код должен оставаться быть понятен вам даже если прилично поддали. Или проснулись среди ночи.
Просто разные концепции
В одном случае цель это эффективный бизнес. Первичен доход, а не инструменты. От инструментов прямой выгоды нет, главное чтобы оно хоть как-то работало, денюжка капает просто за счет бизнес-процессов
В другом случае цель это эффективное ремесленничество, мастерство. Первична производительность этого самого мастерства, количество заказов в единицу времени: чем больше заказов выполнишь, тем больше заработаешь, никаких альтернативных бизнес-процессов, кроме самого ремесленничества, тут нет, денюжку приносят только закрытые заказы. Тут уже вступает в игру разница в инструментах: одни инструменты позволяют достичь результата раньше и с меньшими усилиями, чем другие, но они сложнее и освоить их труднее, как например голый блокнот против навороченной IDE, или например самописный код против фреймворков и библиотек. Тут проявляется разница в подходах: в голом блокноте весь процесс производства ты выстраиваешь сам, а в IDE ты вынужден учить как с ней работать и осваивать те методики разработки, под которую эта IDE проектировалась, точно также и всю архитектуру самописного кода, все требования к нему ты тоже определяешь сам, но при использовании фреймворков и библиотек ты вынужден обучаться тому, как их использовать, вынужден использовать именно тот подход, под который они были спроектированы, а значит вынужден осваивать и использовать ООП, паттерны, заиметь понимание основных алгоритмов и структур данных, их свойств, ведь все это там внутри библиотек и фреймворков зашито, ожидается на входе, и получается на выходе, и с этим хочешь-не хочешь, но придется работать, чтобы повысить эффективность своего мастерства. Без фреймворков и библиотек писать тоже можно, но это явно займет несравнимо больше времени и затрат, чем развернуть фреймворк или подключить библиотеку и сразу получить значительную долю итогового функционала
>Так же ка и стрелочные функции и всякие сокращения я тоже терпеть не могу.
Согласен. Тож не понимаю, накой эти сокращения глупые.
А где примеры проектов написанных правильным ООП?
github.com/yegor256
POJO это фреймворк! Вон оно как... Получается автор не рекомендует использовать ЛЮБОЙ JAVA класс не унаследованный от какого-то специфического объекта. Фтопку JAVA, LOL)
спасибо огромное за комменты - помогли сэкономить время, не смотреть
А какой язык максимально близок к этим идеям?
Автора замкнуло просто си++ и джаве в основном на джаве, автор старый ничего нового в жизни не хочет и поэтому не понимает, что забивать рубанком гвозди такая себе идея. Вся штука в том что современный программист для эффективной работы должен как минимум уметь в три - четыре языка, знать сильные и слабые стороны и использовать под конктретные задачи, а не так что взял джаву эту и громоздишь монолит на миллионы строк из говна и палок. Вторая проблема заказчик который редко когда знает и понимает что ему надо и получается: "потсоны тут проект фигня мне тут бамбуковый шалаш без сортира" к концу проект: "ээээ я чот в Дубае побывал нахуй мне этот шалаш давайте его в небоскреб переделаем, бабки есть я плачу"
@@denisviklov4596 можно говношлёпить "по быстрому", а можно писать грамотный красивый код. Второе конечно же гораздо сложнее, отсюда и такая реакция)
Java например. Попробуйте выкинуть те 3 пункта из вашей практики и посмотрите как вы будете писать код.
Эйфель. Самый чистый ООП.
русский
Доклад интересный, но действительно любопытно было бы увидеть код какого-нибудь web-приложения с таким подходом. Индустриальный стандарт все-таки Spring, Hibernate. Никуда от этого не деться. А в них такой подход, видимо, не уложится..
Доброе время суток всем добрым мальчикам и девочкам столь увлеченным програмированием и и всем тем кто по уши в этом замечательном мире . Я случайно наткнулся на этот ролик и являюсь начинающим из всех начинающих наверно с низов в этой сфере , понравилось програмировать и нравится логика и идея этого занимательного дела пока месь на уровне хобби . Я иногда писав код сталкивался с какой-то невидимой стеной и понимал что процесс програмирования для меня какой-то не комфортный , что я мыслю и представляю себе это иначе ... Этот ролик поставил все на свои места , я понял для себя что я как минимум мыслю именно так . Большой спасибо автору , желаю ему успехов !
Я не программист, но класс это объект? file сам по себе же класс описанный в библиотеке, то получается мы создаем класс f из класса? И чем меньше класс и их больше то это же "простыня". И всё это вместе превратится в процедурное программирование. Комп все сделает все равно по порядку, он не понимает человеческое. Упрощу, например возьмем объект - человек (весьма крупный, у него много чего другого, руки, ноги, голова, потроха и т.п. вплоть до молекул и атомов можно) и это будет очень большой непонятный код как вы говорите. Надо разбить его мельче. Но как это правильно будет тогда? Объясните пжлста.
Я так понимаю ООП - всё объекты и все свойства его закрыты. Например, если открыть объект файл F, то извне никак не должен изменятся. Если у него много параметров то так и должно же быть, Не? Как объект человека разбить? Руки, ноги, голову всё расчленить надо?
Композиция:
class Human{
Head head;
Hand rightHand;
Hand leftHand;
}
@@Anonimus_13 да, да, именно так. Только хотябы,например, вплоть да ногодков опишите. Атрибутов стало больше? Надо разбить мельче говорит автор. То как будет это выглядеть?
@@SSSuzd автор намеренно утрирует, чтобы донести смысл. Вам часто приходится писать приложения, где бизнес интересует модель некой сущности с такой детализацией вплоть до молекул?
А как потом новому в проекте человеку разобраться в этом зоопарке классов?
Легко. Сидеть и читать код первые полгода оплачиваемой работы, вдобавок нагружая специализированных сеньоров своими вопросами по коду.
зависит от задачи, в данном подходе главная логика, будешь широкой композицией объектов, каждый из которых совершает небольшое действие, нужно лишь понять, в како момент ворваться и что добавить.
если какой-то метод лучше, то желательно измерить улучшение, а то слова слишком общие
Ну хорошо, допустим геттеры нельзя.
Есть такой вот объект файл, представляющий файл, открытый моим самописным блокнотом.
Пользователь нажимает "сохранить как" и ожидает оказаться в директории, где этот файл находится и с уже введённым именем файла, чтобы его слегка изменить. Вопрос: где взять имя файла? Тащить по системе от открытия до сохранения? А где хранить? В глобальной переменной? Выглядит как костыли на ровном месте.
Допустим, сеттеры нельзя.
Вот есть у меня лейбл на мордочке, в котором периодически меняется текст. Например - панель состояния текстового редактора, в которой пишется имя текущего файла (которое там класс Файл говорить отказывается). И так, мы открыли файл, ииии... Как нам поменять текст нашего лейбла? Удалить и создать новый лейбл? А какой в этом смысл, если понятнее и менее затратно будет сделать setText().
Ну и без статики же тоже нельзя.
Конечно же, есть у нас в редакторе функция, например, закомментаривание-раскомментаривание строки. Класс String у нас Final, туда мы ничего не можем положить. Куда класть методы работы со строками? Создавать класс без состояния, нарушающий вообще всю суть ООП, ради того, чтобы просто не делать статический класс? Тоже попахивает костылями и пуризмом.
@Yevhen Matasar Допускаю, что иногда такой подход оправдан. Но применять его везде и всюду просто потому что "так надо" - глупость.
Представил установщик, который при каждом изменении значения прогрессбара удаляет его и создаёт новый, со значением на 1% больше)))
@Yevhen Matasar А с доступом к имени файла, видимо, придётся городить костыли, просто чтобы угодить данному товарищу))
Не понимаю помешанность на иммутабельности. Есть действительно подходящие ситуации. Есть не слишком. Как мне быть с той же машиной в момент езды? При каждом изменении угла, на которое повернулось колесо, создавать новую машину? Или колесо новое создавать? Это ни как не коррелируется с реальным миром. В реальном мире объекты не плодятся при изменении своего состояния. И состояние их меняется постоянно...
А если машина состоит из большого количества деталей, то все они изменяют свое состояние и я постоянно буду вынужден проходить нехилый такой цикл инициализации машины. Ясно же, что это правило годится только для атомарных объектов как файл или объект даты...
так про то и речь, автор взял частный случай и пытается из него вывести общее, классическая демагогия
автор говорит, что у машины есть намного меньше свойств, чем вы ей приписываете. Машина может иметь например цвет или раму с колесами, а если вы поменяли раму с колесами на раму с гусеницами, то это уже другой объект будет. А в случае с поворотом колеса - то для этого будут меняться состояния объекта рулевого колеса, например, машина при этом не меняется, колесо тоже не меняется - оно как было колесом, так и осталось.
А где-нибудь есть объяснение ООП через "генетические алгоритмы" ?
А заxем они тебе, несчастный ?
Доля истины в этой идее есть. Особенно если не фиксироваться на объекте как на программной сущности, а представлять его себе как сущность информационную, как некую "душу", которая способна менять тела в виде программных объектов при необходимости, если рассматривать объекты как фрагменты данных, а не конкретные области памяти
Только вместо декораторов стоит пользоваться разумной необходимостью
Вам не нужен класс, который умеет всё. И вам не нужен класс, который не умеет ничего. В каждом конкретном случае вам нужно что-то конкретное, какая-то сущность, которая обладает строго ораниченным функционалом. Это не только ограничивает область контекста, но и стабилизирует архитектуру, делает ее жесткой и устойчивой.
Вот от этой идеи и стоит отталкиваться. Да в принципе она и так везде используется, если посмотреть со стороны: одни и те же по сути данные проходят через множество слоев, но в каждом слое они обернуты в разные объекты с разными характеристиками. Когда объект находится в нижних слоях, он несет в себе множество "лишних" низкоуровневых данных, когда добирается до верхних слоев, в нем остается только самый необходимый минимум данных. И на пути от железа вовне и обратно объект множество раз "перерождается" в разных формах, с разными характеристиками
Только в таком виде та концепция, которую докладчик пытается выразить, обретает хоть какой-то смысл
По поводу ООП. Вообще странным образом получается так, что отчего-то невозможно взять и сделать так, чтобы данные обрабатывались сами по себе внутри своего класса. В основном потому, что бизнес-логика на классы не пилится. Более того, сейчас все паттерны вроде dto, ecs и ioc направлены на то, чтобы отойти от ООП максимально далеко. Отчего у меня вопрос: а так ли нужно ООП?
Да, нужно двигаться в сторону СОП. Ну или АОП, если все совсем плохо...
@@euginekosenko2268 СОП и АОП раньше не слышал. Это о чем?
Много где ООП не нужно. Если код небольшой то проще писать мелкими функциями.
ООП и классы это для очень крупных проектов актуально.
@@KKZ_5000_RUB я попробовал пет-проект на функциональном языке написать. Там конечно не полноценная функциональность - F# все таки, да и я предыдущего опыта не имел и работал паттернами из объектных языков. Но в целом по мне за функциональными языками будущее.
@@KKZ_5000_RUBда ты надоел со своим мелким кодом!
Мелкий код не пишут на Java.
я так понял нужно из Явы сделать Хассель =)
Декораторы классно посмотреть на примере InputStream
Я всё жду когда Егор откроет для себя ФП. Я конечно понимаю, что сокрытие это основная мантра Егора, но сокрытие фактически нужно для борьбы с mutable, и особо не нужно в ФП. Если Егор на подобное согласиться, то наступит покой в его душе. А я бы посоветовал ему честно попробовать Rust в течении пары месяцев.
а как в ФП обстоит дело с огромными проектами?
ООП создан не для сокрытия. ООП создан для упрощения поддержки кода.
По мимо минимального набора команд, которые делают язык Тьюринг полным, весь остальной синтаксис существует для упрощения процесса программирования (что обычно подразумевает упрощение поддержки). Т.е. да доп.синтаксис ООП языков (по сравнению с процедурными языками) упрощает поддержку кода, и доп.синтаксис ФП языков тоже упрощает поддержку кода. Разница в том, какими методами это достигается. Как мы все знаем одна из основных философских предпосылках ООП это сокрытие внутреннего устройства объекта, что конкретно реализуется с помощью инкапсуляции. И все мы знаем, что сокрытие помогает. Оно помогает двумя вещами: во-первых на приватный api не распространяются гарантии для пользователей -- что важный социальный фактор, во-вторых оно дает гарантии разработчику на согласованность сокрытых элементов. Первый пункт на самом деле очень важный и я честно не подумал о нем, когда писал свой комментарий выше -- думаю тут без сокрытия никак не обойтись. А вот второй пункт можно обойти. Дело в том, что гарантии на согласованность это на самом деле гарантии, что никто из вне не придет и не запишет свои странные значения, когда этого нельзя делать. Т.е. на самом деле это защита от записи. Ну и ФП языки решают эту задачу куда элегантнее. Что касается огромных проектов: есть большие распределенные системы на Erlang, например. Ну и на самом деле это конечно миф, что на ФП языках никто не пишет ничего, есть много интересных проектов и на том же хаскели и на F#. Короче мое мнение такое, что в столкновении "ограничение видимости" (как принято в ООП) vs "ограничение прав записи" (как принято в ФП), побеждает второе. Это основная тема доклада и поэтому я считаю, что Егору больше понравятся ФП языки т.к. по моему та проблема, которая его больше всего заботит, там решена лучше.
у меня два существенных пункта -- и потому я их оформлю двумя отдельными комментариями.
вот за счет чего ООП упрощает поддержку кода по сравнению с процедурным программированием?
аналогия: за счет чего происходит развитие науки? за счёт того, что некоторые сущности, которые прошлое поколение воспринимает сложными, комплексными, новое поколение считает простыми, атомарными. не как пачку объектов/свойств, а как один объект.
например, матрицы. сложно оперировать понятиями матриц, если постоянно воспринимать каждую как таблицу чисел. сложно представить себе как выглядит произведение матрицы на обратную -- если представлять её как прямоугольную таблицу чисел. но очень просто -- если воспринимать матрицу как атомарный, неделимый объект со свойствами (хотя, конечно, мы помним, что матрица -- таблица чисел).
соотвественно, упрощение ООП по сравнению с процедурным программированием -- за счёт того, что у нас всё более крупные и сложные вещи используются как простые, атомарные.
и когда мне надо отправить команду на ЮСБ-девайс -- я просто беру объект "девайс" и говорю "вот тебе команда". и мне не надо представлять весь объем логики, за этим скрывающийся. мне не надо помнить, как там управляются потоки, как команда преобразуется в массив байтов, как это скармливается библиотеке вместе с точными координатами отправки, как оно скармливается ядру, как передаётся именно этот тип пакетов, как работает синхронизация итд.
и сокрытие -- это всего лишь способ сделать простой, атомарный объект из огромного комплекса свойств.
так вот, соответственно, вопрос. каким образом ФП делает программирование более удобным?
за счёт чего?
(на всякий случай -- речь идёт не о сокрытии -- ведь сокрытие -- это всего лишь средство, способ добиться того, что написано выше).
2. вы пишите "сокрытие помогает 2 вещами". да. но не теми, что вы описали.
1. самое главное в сокрытии -- это не то, что скрыто. самое главное в сокрытии -- это то, что открыто. Интерфейсы, контракты -- всё это.
сокрытие позволяет нам менять части кода -- и быть уверенными, что это не испортит ничего вне определенного scope. именно сокрытие позволяет сделать "разделяй и властвуй".
именно сокрытие позволяет абстрагироваться от реализации.
и вершина сокрытия -- это не private. и не отказ от сеттеров.
вершина сокрытия -- это интерфейсы. когда объект умеет выполнять определенные задачи -- и всё остальное никого вне объекта не касается.
и именно это ("реализация -- вас не касается") -- сделало ООП настолько удобным для больших проектов.
и по поводу ведения больших проектов на ФП.
я совершенно уверен, что существуют люди, которые в состоянии вести большой проект на процедурном языке. делать это правильно, корректно. так, что код не становится безобразной кучей, к которой противно прикасаться.
и такие проекты -- есть. например, написанные на чистом С.
до сих пор живут и здравствуют.
но это ведь не говорит нам о том, что поддерживать процедурный проект так же просто, как объектный?
таки чем ФП делает поддержку проекта более удобной, чем ООП?
1. Ещё раз. ФП делает тоже самое, но по другому: там другие абстракции, но они служат той же цели. Здесь изобрести другой цели нельзя, все мы хотим одного и того же. Если вы не знаете какие специфические абстракции есть в ФП языках и хотите, что бы я вам тут в комментариях на ютубе всё рассказал, то этого не будет :-)
2. Тут у вас какая-то каша с моей точки зрения, может я вас не так понял, но давайте по порядку.
2.1 Сокрытие очень простой термин, работающий бинарно -- либо открыто, либо закрыто. Говорить, что в сокрытии главное открытие это как говорить, что в boolean важнее всего true, а не false. Толи я вас не понял, то ли вы сказали что-то странное. Если бы в бинарном понятие самой важной была бы одна грань, тогда можно было эту одну грань оставить и само понятие ликвидировать, т.е. "сокрытие нужно, что бы кто-то другой мне тут не накуролесил" это тоже самое, что сказать "сокрытие нужно, что бы открыть в правильных местах, где можно безопасно куролесить".
2.2. Интерфейсы это совсем из другой области. Это из области контрактов и системы типов. Они везде тоже есть. В ФП языках обычно очень богатые системы типов. Эта задача в общем-то везде решается достаточно хорошо, хотя мне не хватает алгебраических типов данных в джаве, но я не могу сказать, что прямо страдаю без трейтов например. Ну т.е. имхо это важная вещь, но она везде решается достаточно хорошо, что в результате нет особой разницы. Но если вас богатые системы типов делают счастливее, то вам тоже понравятся ФП языки, больше чем ООП.
2.3. Ну да, есть Linux, PostgreSQL, проекты написанные на ванильном Си. Мы все их знаем и любим. Я не знают, что это говорит нам, подозреваю, что организация процесса важнее выбора языка. Или что-то в этом духе.
2.4. Я не говорю что ФП делает поддержку удобнее, чем ООП. Я говорю, что в той отдельно взятой вещи, к которой Егор прицепился, подход ФП языков лучше, чем подход ООП языков. Поможет ли это сделать проекты лучше я не знаю. Я говорю, что считаю, что отдельно взятый Егор станет счастливее если перейдет на ФП язык.
Мясников, только в IT.
Предлагаю ввести в ООП паттерн "Гипнотизер", тогда можно будет использовать геттеры и сеттеры. xD
ору
видимо не знает тип что геттеры создавались не как способы доступа а как декоратор (т.е. в теории поле может быть не стрингой а массивом чаров), и то что он переименовал геттер в контент сути не меняет.почти час болтовни ниочем.
Dmitry Egorov Суть не в гетерах, основной посыл был, что данные должны обрабатываться внутри объекта, а не передаваться в неизменном виде от объекта к объекту, используя поле как хранилище данных.
контент может не храниться в объекте файл, внезапно.
Не согласен с Вашим отношением к Null
На мой взгляд Null - величайшее изобретение, если Вы правильно понимаете суть.
Null -это НЕЧТО, Потенциальная возможность реализации чего-либо, в то время как Ноль это НИЧТО, Пустое место
Если помните Творец Создал НЕЧТО из НИЧЕГО
То есть - Ноль это - Я Знаю что здесь пусто, а Null - Я Не знаю что здесь, пусто или нет, мне неизвестно.
Как можно использовать в жизни:
допустим Вам необходимо регулярно делать записи в таблицу, где есть обязательные параметры, например дата и текстовая запись, и ряд параметров классифицирующих и уточняющих эту запись.
И эти параметры вы можете заполнять сразу если время позволяет, либо когда оно появится.
Вот Вы открываете начатую запись и пытаетесь вспомнить, я в этом поле специально ноль или пустое место оставил, или я его ещё не заполнял?
Это ведёт к лишним расходам Вашей психической энергии.
А когда есть Null всё однозначно, значит это поле я ещё не заполнял, а нсли здесь ноль или пустая строка, то это было мной сделано намеренно. Не Важно, Прочерк.
похоже, спикер считает процедурнре и императивное программирование синонимами. процедурное - это всего лишь способ структурирования императивной программы. ровно как и объектно-ориентированное.
В общем-то, всё правильно говорит о сферическом ООП в вакууме, но на практике эта идеальная сферичность мало нужна. В т.ч. и для сопровождаемости. Там кто-то из комментаторов упоминал SmallTalk, он как раз не взлетел исключительно из технических соображений - уж больно медленны были программы на нём в то время. А теперь поздно, да и не нужно, всякие CORBA, DOLE, PDO и прочие «умные объекты» тоже не особо-то взлетели, как и ActiveRecord - основной источник проблем с производительностью и масштабируемостью в Рельсах, AFAIK.
просто с ходу, а как же flyweight? что с этим делать?
34:45 - вот вся суть лекции в 1 предложении. И суть просто в том чтобы одно заменить на другое.
Ну т.е. вы не поняли суть.
Другое одно заменить на если, понятнее станет, длине же той при.
Такая себе критика, особенно про статические классы. Код нужно организовывать, если понятие Class использовать как некий namespace то че париться, надо просто правильно обозначать сам класс. Чтобы компилятор не ломал себе голову созданием конструктора/деструктора.
Я все ждал, что будет разговор про Builder Pattern, и не дождался.
Почему в контексте js если написать public высвечивается как определен но если присвоить свойсвту или методу неработает?
Мне кажется везде должен быть баланс. И очень много маленьких классов это не гуд, и гигантские супер классы тоже явно это плохо. Должен быть какой то разумный компромис между размером класса и количеством классов.
Ты безусловно прав, но кому сейчас интересен здравый смысл?)
Надо научиться правильно читать код. Другими словами, плохой код всегда будет плохо читаться, а хороший код можно читать хорошо (а можно и плохо).
А в c# такая же ситуация как с java в плане ООП? Spring, hibernate.
Не слушайте инфоциган и модников. Майтесь шарпом если маетесь.
И в шарпе вагон объектов-значений:struct,record class,record struct. Record class каешн ссылочный тип,но суть вродь та ж. Вместо изменения состояния и велосипедирования кода для порождения из текущего объекта нового с измененными значениями юзается один и тот же вшитый метод.
Автор прав в большинстве своем. Только геттеры нужны исключительно в тех случаях, когда возвращаются данные, которым не нужна логика по типу user.getName(), плохим тоно было бы делать методы user.getRole(), т.к. это провоцирует пользователей класса писать логику, относящуюся к классу, писать вне класса - а это усложняет поддержку проекта и реально нарушает инкапсуляцию. Статические методы нужны только для тех классов, поведение которых мы не можем изменить, это системные классы по типу List, Set, String.
Но автор не прав в ответе на первый вопрос из аудитории. SRP звучит как "у класса должна быть только одна причина для изменения". И в такой формулировке мы можем спокойно все утилитные методы поместить в один класс и это будет нормально поддерживаемо, уж лучше чем огромный набор утилитных методов.
а поле путь файла он заполняет через конструктор, я так понял?
Да, на 24:30
Зачем ходить по земле ? Это глупо и непрактично. Срочно отращиваем крылья и полетели.
Ооп ради ооп. А Профит то где? Поддерживать сложнее, разрабатывать сложнее. Кало-кода ещё больше будет, если следовать подходу автора. Теперь вместо одного сервисного класса заведем два десятка фасадов.
вся парадима ооп - это именно о профите. инструмент бизнеса для интенсификации разработок за счет глубочайших компромиссов и костылей.
ООП это как конструктор лего, где детали либо похожи либо одинаковы. Много для чего подойдет.
Но для реального творчества и произведений IT искусства нужна глина тонкого помола с мельчайшими частицами, а не конструктор.
Но для очень крупных проектов конструктор лего будет той самой глиной, потому как размеры проекта этом случае гигантские.
Вот и все что нужно знать про ООП. Если проект небольшой, содержит 10 функций, то никакого смысла вообще в классах нет.
@@KKZ_5000_RUB вы говорите не об ооп, а о библиотеках, модулях, классах и интерфейсах. но это не ооп а способы структуризации кода, используемые во всех парадигмах. ооп это всего лишь методы, которые могут хранить состояния, или состояния с определенным поведением. всё остальное (включая классы и интерфейсы) - это только полки, на которые можно разложить эти методы, и к сути ооп не относится.
ООП - это просто один из способов связать данные с кодом, который завязан на эти данные. И всё. Ничего лишнего.
Причем в разных языках эта идея реализована разными способами, со своими особенностями и костылями
Например в одних языках есть структуры данных и процедуры. Хочешь поменять структуру - вызови процедуру и передай в нее структуру: doSome(struct, data)
В других языках решили организовать это в виде ООП, но не переусложнять, и появились составные классы, появилось понятие контекста, this. Процедуры теперь сгруппированы по неймспейсам, по классам, но это все ещё старые-добрые процедуры, и чтобы изменить в них структуру, ее туда нужно явно передать, в аргументе, написать код вида class.doSome(object, data)
А сами структуры, чтобы связать их с классом, стали складывать в анонимные переменные, которые маппят под капотом на какую-нибудь заранее определённую переменную, такую как this или self. И вот мы уже имеем внутри класса странного вида вызовы, типа class.doSome(self, data), чтобы связать процедуры с контекстом, со структурой данных, которая содержит состояние объекта
Ну а в третьих языках решили сдобрить все это синтаксическим сахаром, и спрятали this и self под капотом. При этом под капотом там все также отдельно структуры данных, отвечающие за состояние объекта, и отдельно структура данных, отвечающая за группировку процедур по классам, и в эти процедуры все также передается этот самый self, только теперь это происходит неявно, под капотом, и увидеть это можно лишь разбирая низкоуровневый код, который и работает под капотом языка и сокрыт за всем этим синтаксическим сахаром. И вот у нас появились вызовы вида object.doSome()
И по итогу получается что у нас есть процедурный подход, и есть несколько реализаций ООП подхода, но по факту все это оказывается одно и тоже, просто в одном случае все это работает явно, а в другом неявно
И выходит спорят люди просто из-за разницы в способе организации хранения процедур: в одном случае их хранят с обязательной группировкой по отдельным файлам, а в другом - с необязательной 😂
связать данные с кодом, который завязан на эти данные 🤔. больше поже на определение хард-кода.
если сделать FileUtils как object в kotlin этот дядька успокоится ?))
Интересно, как быть с extension-методами..
Похоже на то, что человек относится к инструменту как к религии.
Это правильное отношение. Я давно мечтаю работать в команде таких людей.
TH-cam Channel в команде людей, которые не могут создать ничего из-за спора о концептах ?
Не могут создать ничего? С чего вы это взяли?
Почему ноль ответственности? Ответственности ноль - это когда вы просто пишете говнокод и аргументируете это тем что это поддерживать придется дальше кому-то другому. Когда вы правильно используете инструементы, которые вам предоставлены, то это не "ноль ответственности". Работу надо делать хорошо всегда
нет, он относится к инструменту как к инструменту, другое дело, что ему очень нравится этим инструментом работать.
такие специалисты мне самому нравятся.
Краткое резюме. Раньше существовали процедурные гитары, вы двигали руками и пальцами и думали как гитара и всю ответственность за производимую музыку брали на себя. А ООП гитара это новый шаг и новое мышлнгие - нажимаешь кнопку сыграй "звезду по имени солнце" и гитара сама играет. Ваши пальцы не могут нарушить инкапсуляцию и вмешаться в производимую мелодию. Вопрос из аудитории. А если я хочу сыграть "дождь идет с утра"? Ответ - тогда вы создаете новый класс, который ответственен только за игру "дождь идет с утра".
Если у нас уже есть класс, который умеет проигрывать музыку (например: "звезду"), то зачем нам ещё один класс для проигрывания "дождя" ? С технической точки зрения, песня "дождь" ничем принципиально не отличается от "звезды", это просто разные комбинации аккордов. В чем смысл создания ещё одного проигрывателя?
ну вы мыслите слишком узколобо, вы говорите о гитареИграющейЗвездуПоИмениСолнце, но гитара имеет метод сыграть мелодию, получает на вход мелодию и играет ее, а уже мелодия является такой-какой мы ее создать хотим хоть "звезда", хоть "дождь", хоть "сигареты"
Критикуя ООП - топит за функциональное программирование)
А как в Swing без статики? Каждый раз новое окно, новую панель?
Посмотри на рекат натив
NULL - читается "нал", а не "нул"
Null - "большая ошибка", не должно быть его в ООП
см. ответ 39:38
@TravelSkul режет слух, когда ноль называют нуль... А нул это вполне конкретное ничто в математике
Докладчик говорить хорошие вещи, но, к сожалению, языком ошибся. В том же Rust работает как часы.