Как стать автором
Обновить

Комментарии 91

Однобоко рассматриваете проблему.

ООП — это не только инкапсуляция, но и наследование, и абстракция, и полиморфизм.

Корни фразы «классы С++ повторяют описание объектов реального мира» уходят корнями в те времена, когда действительно было так.

Сейчас, конечно, немного по-другому, но для новичков такая формулировка является наиболее удобноваримой.
Но зачем путать новичков? Многие потом так и утверждают, что «классы С++ повторяют описание объектов реального мира». Отсюда вытекают все их ошибки в коде, баги. К тому же такая формулировка сильно затрудняет понимание работы алгоритма для них.
Ошибки в коде и баги появляются вовсе не из-за превратного понимания принципов ООП. До тех пор, пока человек не приступил к роли архитекта (либо же он сам себе архитект в более мелких проектах), подобные заблуждения ему не мешают вовсе.
Ммм… В топике рядом 10 лет практики. Часть 1: построение программы человек с многолетним опытом не стесняется говорить, что классы С++ повторяют описание объектов реального мира. У меня такое же представление. Так в чем же ошибка? Если можно — расшифруйте!?
Ни в коем случае не хочу никого обидеть, но почему-то сразу вспомнилось: у деда моего друга было 20 лет водительского стажа, при этом он постоянно путался на более-менее нетривиальных перекрёстках. Почему? Потому что все 20 лет он ездил по одному маршруту: о дома (почти на окраине города) до дачи и обратно.

>Так в чем же ошибка?

Является ли этот класс и его наследники «объектами реального мира»?

class Comparator {
public:
    virtual int compare(Object* obj1, Object* obj2) = 0;
};

Замечу, что некоторые компараторы-наследники могут иметь какие-нибудь данные (константы, коэффициенты и пр.), поэтому заменить класс-компаратор это полиморфной функцией-компаратором можно далеко не всегда.
Пользуйся предпросмотром, пользуйся предпросмотром, пользуйся предпросмотром…
ooad.asf.ru/Pattern.aspx?IdKat=7&IdPat=50
Так как в фразе не было слова «только описания объектов реального мира» я подозреваю, что тут просто недопонимание. Вспомогательные классы нужны практически всегда.
Ну и еще важный момент — объекты не просто повторяют, точнее не полностью повторяют, мало того некоторые детали опускают, делают некоторые допущения, не выделяют отдельные сущности в классы. В общем очень много нюансов. Советую почитать литературу.
ООП — это одно, АТД — это другое. ООП — инкапсуляция и полиморфизм. Наследование затесалось туда случайно и, вопреки всеобщим заблуждениям, не является обязательным атрибутом.

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

Вреднее фразы «описание объектов реального мира», только «массивы передаются по ссылке».
А чего сложного в ООП?
В первую очередь — найти правильное направление на начальном этапе )
Новички как правило не начинают сразу с теорией знакомиться. Они сначала изучают конкретные реализации в языках и часто на этом останавливаются. И при этом считают, что знают ООП.
ООП — это объекты и обмен сообщениями между ними. Все остальное лишь частные случаи реализации парадигмы в конкретном языке.
И моделируют они реальный мир или являются чистыми абстракциями лишь в той мере, в какой это необходимо в конкретной решаемой задаче.
Ответил в статье.
Хм… Для ООП не обязательно иметь какие-то там классы ;)

Берем обычный C, делаем структуры с указателями на функции, договариваемся первым аргументом всегда передавать указатель на this и не обращаться к членам структуры, не являющимся указателями на функции, иначе, чем через этот this. Чем не ООП?
Совершенно верно!!!

ООП — это не возможности языка, это архитектура приложения.

Алан Кей о наследовании:
I didn't like the way Simula I or Simula 67 did inheritance (though I thought Nygaard and Dahl were just tremendous thinkers and designers). So I decided to leave out inheritance as a built-in feature until I understood it better.
Промазал веткой с ответом
>Корни фразы «классы С++ повторяют описание объектов реального мира» уходят корнями в те времена, когда действительно было так.

В каких таких «тех временах» я не мог на реализовать какой-нибудь компаратор в виде C++-класса? Является ли компаратор объектом реального мира? Нет, это всего лишь некоторая придуманная мной функция.
*не мог реализовать
В большинстве случаев в головах у людей каша от того что языки не предоставляют никаких других механизмов абстракции кроме классов, отсюда и смешение понятия класса и абстрактной структуры данных, анонимные классы или функторы (которые объект + оператор вызова) вместо замыканий и т.п.

Программы – суть конвейер по обработке данных, но парадигма Data Flow не очень распространена, вот и городим.
Я встречал мнение, что Erlang-овские процессы по своей сути намного больше подходят к изначальной формулировке сути ООП, данного Аланом Кеем, чем языки с «классами а-ля С++» ;)
s/данного/данной/. Что-то у меня с русским языком не то после праздников.
C++ – эксперимент по тому, сколько абстракций можно протащить в язык C, не сломав ничего и оставаясь производительным. В целом получилось не очень, хотя протащили много разного.

Про erlang я в целом согласен. Дело в том что обмен сообщениями естественно вытекает из идеи позднего связывания.
В первых полностью аппаратных ООП системах каждый объект был отдельным устройством, очевидно, работающим параллельно с остальными. Actor model of concurrency эрланга и скалы как раз этому соответствует.

Только не помню, были ли эти системы реализованы, или так и остались на бумаге. :)
Я бы посоветовал достаточно неплохую книгу тем, кто хочет хорошо разобраться в этой теме:
Гради Буч — Объектно-ориентированный анализ и проектирование с примерами приложений на С++

мне она показалась достаточно подробной и понятной для изучения ООП
Да! Больше статей по C++ за один день, хороших и разных, с разными точками зрения!
Еще ссылки на литературу дайте, как предыдущий оратор, будет полезнее.
www.books.ru/shop/books/352130
www.books.ru/shop/books/30688
www.books.ru/shop/books/487119
www.books.ru/shop/books/806536
www.books.ru/shop/books/816634
www.books.ru/shop/books/728454
www.books.ru/shop/books/455133 — просто полезно для усвоения паттернов и понимания как они могут упростить жизнь. В дополнение к GoF

Ну а в целом с ООП не все так просто. У каждого подхода проектирования свое видение, что есть класс, когда нужно его создавать, как разделять обязанности. Поэтому такая подборочка. Тут от итеративной когда все классы проектируются в юмл, до итеративной, когда класс выделяется только если больше никак, иначе все лепится в текущий класс и очень малое количество юмл диаграмм.
Спасибо огромное за отличную подборку книг!
вот так просто вы навязали Domain model и убили Logical data
на мой взгляд ту статью можно было не читать уже после заголовка. «моя пиписка длинной N. Часть 1»
в свете того, как вы восприняли загловок той статьи, интересно, вы статью все же прочитали или нет?
Не стоит забывать, что ООП это совсем не только способ написания программы. Решить определенную задачу, можно при помощи любой парадигмы программирования (в какой-то — проще, в какой-то сложней). ООП это еще и способ мышления при проектировании. Так как любой программист — человек, ему удобнее мыслить в терминах реальных объектов, предметов из реального мира. Поэтому можно не согласится, с вашей точкой зрения, в которой Вы опровергаете
> «С++ очень прост в том смысле, что классы С++ повторяют описание объектов реального мира. „
Поддерживаю. ООП как раз таки чаще используется для моделирования реальных сущностей: счета, переводы, документы, тарифы, покупатель, продавец итп итп итп. Вот немного процитирую Лармана:

«Проблемы:

Какой класс должен обеспечить реализацию шаблонов High Cohesion и Low Coupling или других принципов проектирования, если шаблон Expert (например) не обеспечивает подходящего решения?
Объектно-ориентированные системы отличаются тем, что программные классы реализуют понятия предметной области, как, например, классы Sale и Customer. Однако существует множество ситуаций, когда распределение обязанностей только между такими классами приводит к проблемам с зацеплением и связыванием, т.е. с невозможностью повторного использования кода.»

А для тех самых нереальных сущностей у Лармана есть вполне толковое название — чистая синтетика(pure fabrication). Цитата как раз оттуда.
> Если сущности «нечего скрывать», то она вырождается в обыкновенную запись данных.

Добавьте, что если у сущности нет состояния, то она вырождается в процедуру (о функциях в C++ говорить не приходится). Как ни странно, о «классах» без данных забывают чаще, чем о «классах» без поведения.
Начинается неделя ООП на хабре?:)
Вообще честно говоря практическая польза от пересказа довольно обширной парадигмы в одной странице довольно мала. Новичкам не поможет, знающие люди найдут скорее повод для споров, чем что-то новое и полезное.
> знающие люди найдут скорее повод для споров

Разве не для этого пишут все статьи на Хабр?
Нет батенька, судя по разделу Q&A. Пишут для кармы :D
1. Подобного рода заблуждения берутся из учебников, в которых для доходчивости приводят примеры из реальности. С методической точки зрения это верно. Но в хороших учебниках идут дальше и поясняют, что объекты не обязательно привязаны к объектам из жизни.
2. Думаю, что это также происходит из-за тяги к абстракциям и нежелании думать о самом процессе разработки. Если программист понимает, что его ООП — это просто общепринятый набор правил, который упрощает ему и его коллегам работу с куском кода (классом), то проблем с пониманием ООП возникнуть не должно.
совершенно бесполезные мудевые рыдания, как для новичков — ибо слишком утрировано и однобоко, так и для про — ибо все рассмотрено на примитивном уровне, да еще и крайне поверхностно.
На мой взгляд стержнем ООП является полиморфизм. Если человек понимает как этим пользоваться, то он владеет основой ООП. Всё остальное не столь важно. Терминология и стиль могут меняться от проекта к проекту, от языка к языку.
Тогда уж интерфейсы
Интерфейсы (в узком смысле слова, как конструкция языка) являются, имхо, средством упрощения реализации и поддержки полиморфизма
Ну… Это как посмотреть, что считать типами и всё такое прочее. Достаточно спорный вопрос.
В python, например, нельзя спрятать данные (по крайней мере без особых ухищрений) — он не является ООП языком?
Данные спрятать нигде нельзя. Разница только в том, насколько просто получить доступ к полю, по мнению разработчика скрытому.

В Python и JS это так же просто как и к открытому, в CL чуть сложнее (slot-value my-object 'some-slot), в C++ всегда можно копаться в памяти, а в Java — через Reflection.
а разве метод/атрибут начинающийся с двух знаков подчеркивания не является приватным?
Нет, если внимательно читать доки, то можно узнать что главное предназначение в исключении конфликтов имен, а не сокрытии. Да и скрытые таким образом методы/атрибуты не составит труда выковырять через словарь.
Читаем Буча и GoF Паттерны ООП (тут даже реальные примеры очень удачные приводятся)… для новичков норм.
Истину глаголите! после статьи про с++ вы вернули мне веру в человечесвто ;)
Мне жалко вас расстраивать, но инкапсуляция и согласованность состояния, про которые говорится в этой статье прекрасно сочетаются с идеей связывания класса с его контролами, описанными в предыдущей.
«Объекты в ООП, как правило, никакого отношения к объектам в реальном мире не имеют.» — это важно понимать.
Суета вокруг дивана.
Абстракция и полиморфизм не имеют прямого отношения к ООП

Главное — понять, что ООП нужно программисту, чтобы контролировать сложность разработки.

//////////////////
Разве сложность разработки не контролируется за счет той же абстракции и полиморфизма? Ты сам себе противоречишь.

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

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

*fixed

Вспомнилось

О проектировании иерархии классов говорили все, кому не лень — одни по делу, другие болтали «об имитации объектов реального мира».
Jeff Alger, «C++ for real programmers»
У вас проблемма в том что вы сами научились, но учить других людей пока не умеете. Для новичков так пишут, чтобы учить их по индукции (от частного к общему), а не по дедукции. Большинству населения планеты по индукции учиться проще.Зато работать проще именно с помощью дедукции.
«Типичной ошибкой С++ программиста является выбор С++ в качестве языка программирования»/Александерску/

«Не читайте Александреску»/Степанов/

«На Си можно писать объектно»/толковые люди/ (это к указателю на функцию сортировки — полиморфизм в данном случае налицо)

«Хороший, плохой… Главное — у кого ружьё»/Нэш из скобяных товаров/

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

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

так что спор является ли объект языка отображением объекта языка имхо является обычным холивором, причём спорщики нехотят уточнить что такое объект в одном языке и в другом.
Исходя из вашего UPD — вы слабо понимаете то, что пытаетесь объяснить другим.
На правах бреда и согласно вашему пассажу:
пример абстракции:
int x;
пример полиморфизма:
x=3;
x=5;
> пример абстракции:
> int x;

И какую же более высокоуровневую структуру данных или вычисления описывает данная абстракция?
Ту же что и абстракция void sort(int* array, int size);
Вопросы к автору.
sort(int* array, int size); описывает операцию сортировки через более низкоуровневые операции сравнения и обмена.

int x; операцию сортировки через что-то более низкоуровневое не описывает.
int x; описывает поведение некой абстракции («переменной целого типа») при использовании её в качестве операнда операторов и других синтаксических конструкций :)
Через какие более низкоуровневые сущности встроенные в язык?

int x; описывает поведение, но это основная фича языка, а не абстракция над ними.
int x — это абстракция над технической реализацией целых чисел (ну, к примеру, где их хранить — в регистрах, в памяти), которая встроена в язык и для эффективности реализована (в C++), видимо, в машинных кодах. Разные языки могут иметь разные «фичи», и то, что в одном языке будет встроенным, в другом нужно будет реализовывать самому. Абстракции от этого абстракциями быть не перестают.

Ну, например, в питоне диапазон для целых чисел ограничен только оперативной памятью, а в C++ — разрядностью системы, и чтобы в C++ реализовать питоньи целые числа, диапазон которых не ограничен разрядностью системы, нужно писать код — см., например, gmplib.org/.
Пожалуй, отправлю и вас читать SICP.
Читал я его, товарисч. SCIP по-моему как раз и учит не представлять себе язык программирования как данное свыше чудо. Мне кажется, вы не поняли, что суть спора про int у нас — терминологическая, а то, как XaBoK неудачно попытался съехидничать, к делу особо не относится.
Разве была речь про язык? :)

P.S. Меня не отправляйте, SICP с вашей (кажется) подачи уже прочёл, правда подсел на Erlang (just for fun, как лет 20 назад на FORTH :( )
Чтобы не щеголять дальше своими знаниями, возьмите и почитайте SICP.
Спасибо. Продолжило устаканиваться в голове.
Я уже встречал статью с похожей идеей, что реальные объекты очень плохой пример для ООП. Там как раз классические студенты упоминались.
в статье не хватает критерия применимости.
Другой пример. Предположим в программе требуется динамическая загрузка модулей. Есть состояние — набор уже загруженных модулей. И поведение легко просматривается — «загрузить модуль», «выгрузить модуль». К чему этот пример? К тому, что никакой связи с объектами в реальном мире здесь и в помине нет.

А почему вы думаете, что модуль — не объект реального мира? Он существует на жестком диске, в памяти, вы загруженные модули неким абстрактным объектом и описываете. Почему же не объект реального мира-то?
Если уж на то пошло, то модуль некая информация, представленная в виде состояния неких объектов. Информация, представленная состоянием какого-то объекта (или системы таких объектов), по-моему, никак не равна это объекту. Жёсткий диск — объект, информация — его состояние
Иногда нужно разжевывать все по простому, иначе никак. Ещё бы эти новички прочитали статью, а то ведь многие пройдут мимо даже не прочитав пару абзацев.
Какая очаровательная схоластика! Сколько все-таки ангелов на конце иглы? 4765 или 1 миллиард двести? Если мир есть мое представление, то можно ли назвать мое представление миром? Какое однако чистое парение ума! Хорошо, собака, излагает. Учитесь, предводитель.
Да, кстати
Человек с которым вы спорите практик, решает реальную проблему. Можно даже назвать ее низменной. Ну что с них практиков возьмешь. Неучи. Думают, что если ООП, так все оно так и есть.
Спасибо за критику. Согласен с тем, что слишком упрощённо описал перенос объектов реального мира в С++. Чуть дополнил соответствующее место в статье. К сожалению, их взаимоотношения настолько разнообразны и разноплановы, что я бы не рискнул сказать что даже ваша статья описывает их достаточно полно.
Что касается езды по одному маршруту — не претендую на Истину, Светоча и т.п. ) Учусь также, как и вы, до сих пор. С моей точки зрения, мне удалось более или менее свести наработки в некую законченную систему, пусть и сумбурно изложенную. В этом смысле я и вижу свою заслугу, а ни в коем случае не в особых, эксклюзивных знаниях.
С другой стороны, для начинающих требуется сформулировать более или менее законченное и простое правило. Что я и пытаюсь сделать. Если сможете сформулировать более простое и точное — напишите, возьму его на вооружение.
Просто вы писали о практическом применении связки ООП+C++ со стороны инженера, а этот человек решил выступить в роли знатока CS и пройтись по терминологическим ошибкам, и в итоге написал полную бредятину, так как вообще не понимает что такое чистое ООП со стороны CS.
Ваша статья была гораздо полезнее.
Хорошая идея у статьи.
Хорошо когда люди думают.
У людей разные представление о мире.

Выводы делайте сами.
Еще бывают любопытные заблуждения, связанные с наследованием. Уж не буду говорить про то, что очень многие используют этот механизм для повторного использования кода, ломая все теоретические благие намерения.
Забавно задавать вопрос о квадрате и прямоугольнике — кто кого наследовать должен? :)
прямоугольник от квадрата
Ну и то — зависит от контекста.
Именно! Зависит от того, какое поведение мы включаем в модель. Без этого задача поставлена некорректно. А многие сразу бросаются отвечать :)
Я привел классический ответ. Если добавить овал и треугольник — то без интерфейсов обычно не обойтись :)
С++ очень прост в том смысле, что классы С++ повторяют описание объектов реального мира.
— согласен что утверждение неполное ( или неверное — как кому нравится). Исходя из своего опыта скажу так, может кому пригодится: классы должны отражать свойства и поведение объектов и (или) понятий предметной области с которой мы работаем. И да — это архитектурный подход. Более того в каждом языке разный. В JavaScript вообще нет классов как таковых и ООП там прекрасно живет.
У сущности есть поведение
— не факт, те же DAO зачастую не содержат поведения; или же поведение ваших объектов настолько сложно, что вы выносите его (поведение) в отдельный класс или классы, и ваш объект становиться «Value Object».

P.S. С C++ очень мало знаком, поэтому говорю в целом.
Более развернуто, класс объектов (в понимании ООП) используют, если…

… у некоторой сущности есть поведение, зависящее от внутреннего состояния этой сущности.


В моем понимании объект — это контейнер для объединения информации и/или функций. Набор переменных тоже может быть объектом, хотя поведения у него нет. И функции тоже можно завернуть в объект, хотя у него не будет состояния. Получится смесь ООП и функциональщины.
Отлично. В головах засело — ооп это классы.
На это вы привели хороший пример на с. Прямо моду разрушили ;)

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

Публикации

Изменить настройки темы

Истории