LINUX.ORG.RU

Моё понимание ООП

 


1

1

Мою прошлую тему загадили и утопили в молоке, завалили вопросами типа «а что ты понимаешь под ООП». И жалуются что я не отвечаю. Но не на все вопросы есть простые ответы. «Один дурак может задать столько вопросов, что сто мудрецов не смогут ответить!». И всё же я попробую представить своё видение.

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

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

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

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

Сразу хочу отметить, что я не против банкоматов, они не идеальны, но пока безналичный расчёт не везде принимают, приходится ими пользоваться. Проблема ООП в том, что в нём всё является таким «банкоматом» и везде принимается только нал. Любому очевидно, что когда имеешь дело с банкоматами, ты не можешь ничего оптимизировать.

ООП - это такая модель, в которой «всё является объектом», то есть данные заворачиваются в объект и вместо естественного для вычислительной машины хода обработки данных «данные на входе -> данные на выходе», твой код имеет дело с интерфейсами, т.е. идёт общение с «чёрным ящиком», который «сам знает что делать».

Простой пример: веб-браузер HTML+CSS+Javascript В этом примере HTML - это данные в чистом виде. Они не «знают» как себя отобразить. CSS - тоже данные. Это не объекты. И есть Javascript код, который имеет полный доступ к дереву документа. И когда ты пишешь веб-браузер, у тебя данные на входе - веб страница на выходе - это информационн-ориентированный подход (Data-oriented), в центре которого данные, а не объекты. Сохраняя страницу в формате .pdf ты тоже создаёшь данные на выходе. Эти данные можно отправить в другую программу для дальнейшей обработки. Это как инструмент.

★★

Последнее исправление: svyatozar (всего исправлений: 4)
Ответ на: комментарий от metaprog

Свитчи заменить возможно с помощью полиморфизма, но фабрика всё равно нужна так или иначе.

anonymous
()
Ответ на: комментарий от anonymous

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

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

Дополнение к определению тоже смысла как такого не привносит. Это общие слова.

позволяют эффективно решать задачи

обеспечивая удобное моделирование

Каким же образом? Ответа в определении не содержится. Какое-то безосновательное обещание.

То есть ответов никаких не даёт, а уволит в сторону и добавляет ещё больше вопросов (включая поиск определений из буллшит-бинго).

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

WitcherGeralt ★★
()
Ответ на: комментарий от anonymous

Делается функциями, так же как и уничтожение объекта. В визуалке это, кстати, еще очевиднее. Например, создание, испольование и уничтожение TCP-сокета:

https://postimg.cc/jLJqgc1V

metaprog
()
Ответ на: комментарий от metaprog

Судя по скриншотам - это что-то типа Blueprint в движке Unreal? Мне всегда было удобнее писать текстовые скрипты.

Кстати, в движке Godot тоже есть что-то подобное.

svyatozar ★★
() автор топика
Ответ на: комментарий от svyatozar

Это LabVIEW. Не моя разработка, но на ней я делаю Метапрог. Та же схема в Метапроге (уже моем):

https://postimg.cc/NybVbScJ

Судя по скриншотам - это что-то типа Blueprint в движке Unreal?

Кстати, в движке Godot тоже есть что-то подобное.

Сходство очень отдаленное. Оно по сути к сишке ближе, так как там типизация, похожая на сишную (а в Метапроге так вообще за основу взята именно сишная типизация, с указателями). Короче, если интересно - можешь в моем треде или Метапрог Онлайн поспрашивать.

metaprog
()
Ответ на: комментарий от WitcherGeralt

Нет бы сказать, что это просто способ организации кода такой

Ничего себе просто. В нагрузку к способу организации кода идет набор концепций, в терминах которого эта организация (и вообще вычислительный процесс) описывается. Причем набор не самый простой для понимания и использования.

пойдёт искать альтернативные способы организации кода. Ничего внятного не найдёт и осознает, что ООП есть тру

Кому и кобыла невеста, ага.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от Nervous

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

Причем набор не самый простой для понимания и использования

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

WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

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

Чтобы «просто сформулировать три основополагающих принципа» (тм), нужно сначала незаметно протащить как минимум определение объекта. Что он из себя представляет вообще. А представляет он из себя малоприятную мешанину из identity, mutable state и behavior, заодно выполняющую роль namespace. Но об этом неофит узнает потом. Для начала ему хватит укоризненного взгляда гуру с выражением «ну просто объект, ну ты же понимаешь, что я хочу сказать».

Конечно, понемает. Проблема в том, что понемает каждый по-своему.

Довольно очевидные вещи … их нет нужды даже формулировать

Дада, плавали, знаем. «Очевидно, что» и «легко показать», теперь банановый.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 2)
Ответ на: комментарий от Nervous

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

Конечно, понемает

Вот и будет понемать на вполне конкретных примерах, смысл существования которых ему доступно объяснили, а не мыслить в абстратных категориях и потом уже в 40 лет по-прежнемк не одупляя бурчать про плохое непонятное ООП как ТС.

WitcherGeralt ★★
()

Говорил в старой теме, повторю и тут. Было бы интересно, если бы отвечающие сообщали какой язык программирования используют в работе. Предполагаю, что было бы:

  1. ООП - просто. Использую Python.
  2. ООП - безальтернативан. Использую Java.
  3. ООП - кошмарный ужас, польза от которого сомнительна. Использую C++.

Для иллюстрации можно вспомнить всякие виртуальные деструкторы, конструкторы копирования и присваивания в C++. Нужно ли это программисту на C#? Нет, потому что, например, деструктор там не используют для уникальных способов освобождения ресурсов. Вместо этого используется Dispose(), но и он нужен в меньшем количестве случаев.

Kogrom
()
Ответ на: комментарий от Nervous

Чтобы «просто сформулировать три основополагающих принципа» (тм), нужно сначала незаметно протащить как минимум определение объекта. Что он из себя представляет вообще. А представляет он из себя малоприятную мешанину из identity, mutable state и behavior, заодно выполняющую роль namespace. Но об этом неофит узнает потом. Для начала ему хватит укоризненного взгляда гуру с выражением «ну просто объект, ну ты же понимаешь, что я хочу сказать».

Конечно, понемает. Проблема в том, что понемает каждый по-своему.

Вот именно! Говорим «объект», а подразумеваем «интерфейс», по сути, ширма. Ты, разрабатывая код, можешь не знать что переопределённая функция запрашивает данные в интернете. (И тут открытость кода не при чём, как кто-то писал. Наследованный класс могут создать в будущем другие люди.) Сколько время на этот запрос нужно? Никто не знает. Объект - это не просто чёрный ящик, а чёрный ящик встроенный в стену (кому не нравится аналогия с банкоматом), с подъездом и, возможно, с фурами с водителями, которые в постоянно в пути, по своим маршрутам и по своему графику. За твои деньги!

Или структура - счёты у тебя в сейфе. Открыл своим ключом и сам прочитал/записал/передал кому надо. Об этом ведь речь!

svyatozar ★★
() автор топика
Последнее исправление: svyatozar (всего исправлений: 4)
Ответ на: комментарий от WitcherGeralt

разбираемся как с этим работать, что паттерн, что антипаттерн

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

Зато все при деле %)

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от svyatozar

Вот именно! Говорим «объект», а подразумеваем «интерфейс», по сути, ширма. Ты, разрабатывая код, можешь не знать что переопределённая функция запрашивает данные в интернете. (И тут открытость кода не при чём, как кто-то писал. Наследованный класс могут создать в будущем другие люди.) Сколько время на этот запрос нужно? Никто не знает. Объект - это не просто чёрный ящик, а чёрный ящик встроенный в стену (кому не нравится аналогия с банкоматом), с подъездом и, возможно, с фурами с водителями, которые в постоянно в пути, по своим маршрутам и по своему графику. За твои деньги!

Ты сейчас «помножил на ноль» и полиморфизм с калбэками/лямбдами/ссылками на функции… Считай сам на своих счётах дальше…

yyk ★★★★★
()
Ответ на: комментарий от metaprog

Хватит пиарить свой говнопрог, он никому даром не нужен

anonymous
()

Моё понимание ООП

Это неологизм к «моя борьба»?

Aswed ★★★★★
()
Ответ на: комментарий от WitcherGeralt

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

Похоже Вы не (ООП-)разработчик, раз с объектами и ООП проблемы. Что в Вашем понимании объект?

Определение объекта и как говорится: «покажите код», если не затруднительно.

anonymous
()
Ответ на: комментарий от WitcherGeralt

Полезный совет самому себе. Определение дано.

anonymous
()

«мое непонимание ООП»

fixed

olelookoe ★★★
()
Ответ на: комментарий от hobbit

полезно при умелом и нефанатичном использовании

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

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

Kogrom
()

ООП мало используется. Сейчас идёт переход на модульное программирование. Процедуры/функции + интерфейсы.

anonymous
()
Ответ на: комментарий от Kogrom

STL - не ООП. Нет никакой инкапсуляции. Итераторы дают полный доступ к данным в контейнерах на низком уровне - указатель. Сама последовательная итерация данных из одной функции - это уже информационно-ориентированный подход по типу СУБД.

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

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

svyatozar ★★
() автор топика
Последнее исправление: svyatozar (всего исправлений: 1)
Ответ на: комментарий от Kogrom

Но это всё относительно безопасно в плюсах.

STL это скорее навороченные говномакросы. Никаких проверок, ничего. Из пустого стека можно извлекать элементы с последующим сегфолтом.

anonymous
()
Ответ на: комментарий от svyatozar

STL - не ООП. Нет никакой инкапсуляции. Итераторы дают полный доступ к данным в контейнерах на низком уровне - указатель.

Это с натяжкой можно сказать только о vector-е, потому что там данные специально расположены друг за другом. Что на счёт map? Да даже list прячет указатели элементов друг на друга. Так что в большинстве контейнеров инкапсуляция вполне есть.

Kogrom
()
Ответ на: комментарий от anonymous

Никаких проверок, ничего.

Среди принципов ООП я не нашёл «проверок». С другой стороны, для многих контейнеров есть метод at(), если надо больше надёжности.

Kogrom
()
Ответ на: комментарий от Kogrom

STL - не ООП. Нет никакой инкапсуляции. Итераторы дают полный доступ к данным в контейнерах на низком уровне - указатель.

Это с натяжкой можно сказать только о vector-е, потому что там данные специально расположены друг за другом. Что на счёт map? Да даже list прячет указатели элементов друг на друга. Так что в большинстве контейнеров инкапсуляция вполне есть.

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

svyatozar ★★
() автор топика
Ответ на: комментарий от svyatozar

Если говорим о доступе к элементам vector-а через указатель, то тут можно согласиться с поломанной инкапсуляцией, потому что тут мы получаем доступ сразу ко всем данным и можем их править через какой-нибудь memcpy(). Если говорим об итераторе - то через него мы получаем доступ только к одному элементу. Итераторы для каждого контейнера ведь имеют свой тип, совместимый только с этим контейнером. И как мы можем рассматривать list, например, как структуру, если у него элементы раскиданы по куче в произвольном порядке?

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

Kogrom
()
Ответ на: комментарий от Kogrom

Это даже не ООП. Это просто MUST HAVE. Стек должен проверять, не пустой ли он, прежде чем вытаскивать элемент. Этому учат студентов и школьников. И степанову со страусихой надо сначала школу закончить.

anonymous
()
Ответ на: комментарий от svyatozar

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

Ну ёкарный тулуп. Данные контейнера - это не состояние объекта контейнера. Это для него сторонние данные.

А состояние объекта Vector - это вот эти все empty, size, max_size. Они доступны только через методы, то есть инкапсулированы. Это обычное ООП.

James_Holden ★★★★
()
Ответ на: комментарий от James_Holden

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

Ну ёкарный тулуп. Данные контейнера - это не состояние объекта контейнера. Это для него сторонние данные.

А состояние объекта Vector - это вот эти все empty, size, max_size. Они доступны только через методы, то есть инкапсулированы. Это обычное ООП.

Да даже если взять пустой контейнер STL. Виртуального деструктора нет, виртуальных функций - тоже. Ни наследования, ни полиморфизма. Где тут ООП?

svyatozar ★★
() автор топика
Ответ на: комментарий от Kogrom

Если говорим о доступе к элементам vector-а через указатель, то тут можно согласиться с поломанной инкапсуляцией, потому что тут мы получаем доступ сразу ко всем данным и можем их править через какой-нибудь memcpy(). Если говорим об итераторе - то через него мы получаем доступ только к одному элементу. Итераторы для каждого контейнера ведь имеют свой тип, совместимый только с этим контейнером. И как мы можем рассматривать list, например, как структуру, если у него элементы раскиданы по куче в произвольном порядке?

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

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

svyatozar ★★
() автор топика
Последнее исправление: svyatozar (всего исправлений: 1)
Ответ на: комментарий от anonymous

Это даже не ООП. Это просто MUST HAVE. Стек должен проверять, не пустой ли он, прежде чем вытаскивать элемент.

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

В наше время всё это экономия на спичках. Соответственно, тут имеет шанс какой-нибудь Rust, у которого такие проверки есть. Но у Rust вроде бы нет синтаксиса для полноценного ООП. Возможно, я ошибаюсь. Вот некто создаёт паттерны GoF на Расте. Оценить, насколько они работоспособны и удобны в использовании я пока не могу.

Kogrom
()
Ответ на: комментарий от svyatozar

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

anonymous
()
Ответ на: комментарий от Kogrom

Но у Rust вроде бы нет синтаксиса для полноценного ООП

Конечно, нет. И не случайно, потому что сейчас никому не упёрся этот «полноценный ООП». Вообще поражаюсь лору: вроде бы передовой сайт рунета, а сколько тут замшелого народа, который до сих пор топит за такие ошибки индустрии, как Perl, ООП, обработку ошибок через исключения, нуллабельность и прочее (дополните список)…

hbee ★★★★
()
Ответ на: комментарий от hbee

Вообще поражаюсь лору: вроде бы передовой сайт рунета, а сколько тут замшелого народа, который до сих пор топит за такие ошибки индустрии, как Perl, ООП, обработку ошибок через исключения, нуллабельность и прочее (дополните список)…

Так открой глаза этим никчемным людишкам, где нет этих ошибок, чем пользоваться, на чем программировать? :)

BRE ★★
()
Ответ на: комментарий от BRE

Так открой глаза этим никчемным людишкам, где нет этих ошибок, чем пользоваться, на чем программировать? :)

Ответ очевиден: Rust.

hbee ★★★★
()
Ответ на: комментарий от svyatozar

ООП ни разу не логичен.

Логичен и понятен.

Есть много литературы на эту тему.

Ты не понял моего сообщения. Выкинь литературу нахрен и начинай учиться думать своим мозгом.

Часто приводится пример: квадрат - это прямоугольник.

Это понятный для начала пример. Как любой обучающий пример к нему можно придраться.

Но тогда функция изменения ширины либо будет квадрат делать прямоугольником

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

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

vtVitus ★★★★★
()
Ответ на: комментарий от BRE

А что из больших проектов написано на этом волшебном языке?

Из того, что я знаю, с чем работал — блокчейны Polkadot и Solana. Это большие сложные проекты, особенно первый.

Из вакансий попадались разработка каких-то движков баз данных, медицинский софт, игровой движок… То есть что-то такое большое коммерческое разрабатывается на Rust.

hbee ★★★★
()
Последнее исправление: hbee (всего исправлений: 2)
Ответ на: комментарий от hbee

Из того, что я знаю, с чем работал — блокчейны Polkadot и Solana. Это большие сложные проекты, особенно первый.

Я для интереса клонировал Polkadot иииии… там 137K строк кода на Rust. Это не большой проект. Второй как я понимаю еще меньше. И время жизни проекта 2,5 года - тоже не показатель.

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

Достоинства C++|Java|etc в том, что их модели проверены временем, известны их сильные и слабые стороны и проработаны рекомендации, позволяющие их использовать в больших проектах.

BRE ★★
()
Последнее исправление: BRE (всего исправлений: 7)
Ответ на: комментарий от hbee

Rust

Проверил реализацию GoF на unsafe - не нашёл. Зато очень много использования Box. То есть, если я правильно понимаю, в коде, который будет использовать эти заготовки, будет сплошной unsafe.

О чем это мне говорит? О том, что Rust не сможет заменить Java, C#, Python. Потому что полиморфизм такой же небезопасный как в C++. То есть, в GUI, например, в сложных системах документооборота, в крупных играх от Rust-а ждать чего-то не приходится. Тут он может и не хуже плюсов, но у тех уже есть огромное количество наработок.

Мои слова подтверждаются тем, что на Rust-е любят переписывать консольные утилиты, которые ранее были написаны на си или плюсах. Да, тут у Rust-а есть преимущества. В других областях перспективы пока не видны.

Kogrom
()
Ответ на: комментарий от Kogrom

Соответственно, тут имеет шанс какой-нибудь Rust, у которого такие проверки есть

В С++ есть все те же проверки что и в Rust, даже больше проверок(большинство unsafe методов в Rust не делают проверки)

https://imgur.com/a/P6Ikrsd

Можно оставить их и в релизе, достаточно добавить макрос _ITERATOR_DEBUG_LEVEL=1

Всё это документировано: https://docs.microsoft.com/en-us/cpp/standard-library/iterator-debug-level?view=msvc-160

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 2)
Ответ на: комментарий от fsb4000

microsoft

А то же самое для gcc?

_ITERATOR_DEBUG_LEVEL=1

Это полумеры. Для полного счастья надо ещё переполнение целочисленных типов ловить, деление на ноль и т.д.

Kogrom
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.