Почему ООП сложно? [закрыто]


92

Когда я начал использовать объектно-ориентированный язык (Java), я просто стал «крутым» и начал писать код. Я никогда не задумывался об этом до недавнего времени, прочитав много вопросов об ООП. Общее впечатление, которое я получаю, это то, что люди борются с этим. Поскольку я не думал об этом как о сложном, и я не сказал бы, что я какой-то гений, я думаю, что, должно быть, что-то упустил или неправильно понял.

Почему ООП трудно понять? Это сложно понять?


72
Я согласен с: это не сложно понять, просто трудно освоить. Программирование в целом так.
Стивен Эверс

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

5
@ acidzombie42: функционал совсем не странный. вам не нужно писать список команд, чтобы изменить содержимое переменных, которые представляют местоположение в ОЗУ. переменные представляют значения, вы не меняете значения; 42 остается 42, х остается х - кем бы ни был х. вы пишете функции, отображающие их параметры в результаты. значения: числа, списки значений, функции от значений до значений, программы, которые создают побочные эффекты и полученное значение при выполнении, и многое другое. таким образом, результат основной функции будет вычисляться компилятором, то есть программой, которая может быть выполнена.
комонад

5
Я недавно изучал Хаскель. Чем больше я узнаю и пойму о функциональном программировании, тем больше я чувствую, что ООП труден. Я думаю, что основная причина этого заключается в том, что ООП пытается связать воедино данные (объект / класс) и функцию, которая над ними работает (метод). Это является источником проблемы, и многие шаблоны проектирования ООП разработаны, чтобы избежать связывания данных и функций вместе. Например, фабричный шаблон используется для отделения конструктора (который является функцией) от фактического объекта, над которым он работает.
ming_codes

1
Потому что это неправильно. Это должно быть предметно-ориентированное программирование, в котором субъект выполняет действие (глагол), а объект получает действие - Джон бросил мяч. Так что johnsBall.throw () на самом деле не имеет смысла.
Крис Кадмор

Ответы:


120

Мне лично было легко понять механику ООП. Трудной частью для меня было «почему». Когда я впервые столкнулся с этим, мне показалось, что это решение проблемы. Вот несколько причин, почему я думаю, что большинству людей это трудно:

  1. ИМХО преподавание ОО с самого начала - ужасная идея. Процедурное кодирование не является «плохой привычкой» и является подходящим инструментом для некоторых рабочих мест. В любом случае отдельные методы в ОО-программе выглядят довольно процедурно. Кроме того, прежде чем изучать процедурное программирование достаточно хорошо, чтобы его ограничения стали видимыми, ОО не кажется студенту очень полезным.

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

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


5
Сказочный ответ, особенно номер 1. Конечно, методы в ОО выглядят как методы в процедурном языке, но теперь они размещаются в объектах, которые также имеют состояние.
Дэн Розенстарк

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

7
+1 за "Трудная часть для меня была" почему "этого". Требуется некоторое время и усилия, чтобы понять и применить основы языка (инкапсуляция), принципы проектирования и методы рефакторинга, к общим решениям (шаблонам проектирования).
Белун

12
Я согласен с # 1, с оговоркой, что вам нужно лучше объяснить ОО людям, которые уже знают, как программировать процедурно, чем это было, когда я учился. Нет, не полезно и не информативно говорить о Catклассе, который наследуется Mammal, использовать реальный пример из реальной программы, которую мы написали бы процедурно. Как простая структура данных.
Carson63000

4
-1 Шаблоны дизайна сегодня переоцениваются. Они важны, конечно, но: во-первых, они важны для всех парадигм: функциональных, структурированных, а также ОО; и во-вторых, они не являются частью парадигмы, а просто удобным дополнением, которое вы можете использовать, как и многие другие. @SoftwareRockstar хорошо объясняет это в своем ответе.
CesarGon

56

Я думаю, что есть несколько факторов, которые еще не были упомянуты.

Прежде всего, по крайней мере, в «чистом ООП» (например, Smalltalk), где все является объектом, вы должны изогнуть свой ум в довольно неестественную конфигурацию, чтобы думать о числе (только для одного примера) как об интеллектуальном объекте вместо просто значение - поскольку в действительности 21(например) действительно является просто значением. Это становится особенно проблематичным, когда, с одной стороны, вам говорят, что большим преимуществом ООП является более точное моделирование реальности, но вы начинаете с того, что очень похоже на ЛСД-вдохновленный взгляд даже на самые простые и очевидные части реальность.

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

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

Просто для примера рассмотрим "автомобиль" как класс. Довольно легко увидеть, что подавляющее большинство того, что большинство людей считает «автомобилями», имеют четыре колеса. Большинство людей, однако, видели (по крайней мере, изображение) автомобиль только с тремя колесами. Некоторые из нас нужного возраста также помнят гоночный автомобиль или два из ранних 80-х (или около того), которые имели шесть колес - и так далее. Это оставляет нам в основном три варианта:

  1. Ничего не утверждайте о том, сколько колес у автомобиля - но это приводит к неявному предположению, что оно всегда будет 4, и коду, который может сломаться для другого числа.
  2. Утверждают, что все машины имеют четыре колеса, и просто классифицируют эти другие как «не автомобили», хотя мы знаем, что они действительно есть.
  3. Разработайте класс таким образом, чтобы на всякий случай допускалось изменение количества колес, даже если есть большая вероятность, что эта возможность никогда не понадобится, не будет использована или должным образом проверена.

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

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

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

Однако давно базы данных в значительной степени сходились по реляционной модели (и хотя они не являются SQL, на этом уровне абстракции текущие базы данных «NoSQL» также являются реляционными). Преимущества реляционной модели достаточно хорошо известны, поэтому я не буду повторять их здесь. Я просто отмечу, что наиболее близким аналогом реляционной модели, которую мы имеем в программировании, является универсальное программирование (и извините, но, несмотря на название, дженерики Java, например, на самом деле не подходят, хотя они представляют собой крошечный шаг в правильное направление).


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

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

Похоже на таблично-ориентированное программирование , хотя я скажу, что пришел к осознанию того, что ООП - не серебряная пуля разработки программного обеспечения.
OnesimusUnbound

1
@OnesimusUnbound: разница в том, что универсальное программирование - это реальный, практический способ добиться чего-то, в то время как программирование на основе таблиц - это в основном сумасшедший бред о теории о том, как что-то может работать (прочитайте старые посты TopMind в comp.object, и вы Посмотрим, что я имею в виду - на самом деле, посты могут не все быть старыми; насколько я знаю, он продолжается даже сегодня).
Джерри Коффин

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

26

ООП требует умения мыслить абстрактно; дар / проклятие, которое на самом деле имеют немногие люди, даже профессиональные программисты.


35
Все программирование абстрактно.
JeffO

28
@ Джефф О - Я не согласен. Программирование требует только умения рассказать кому-то, как сделать что-то шаг за шагом. Если вы можете рассказать кому-нибудь, как приготовить бутерброд с арахисовым маслом и желе, у вас есть возможность вводить команды в программный интерфейс. Это совершенно другой набор навыков, чем абстрактное моделирование бутерброда ap, b & j и того, как он взаимодействует с миром.
Джон Крафт

16
Вручить кому-то 2 карандаша, а затем - 1 карандаш и спросить, сколько у них карандашей, - это конкретно. 2 + 1 = 3 является абстрактным.
JeffO

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

2
@KonradRudolph Отличный момент. +1 за «Все остальное будет слишком сложно без абстракций» .
Картик Сринивасан

21

Я думаю, что вы можете обобщить основные трудности следующим образом:

// The way most people think.
Operation - object - parameters
// Example:
Turn the car left.

// The way OOP works conceptually
Object - operation - parameters
// Example:
Car.Turn(270);

Конечно, люди могут привыкнуть к отображению «левого» как 270, и да, сказать «Car.Turn» вместо «Turn the Car» не такой большой скачок. НО, чтобы хорошо разбираться с этими объектами и создавать их, вы должны обратить то, что вы обычно думаете.

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


7
Хорошее понимание. Я думаю, проблема в том, что в реальной жизни «объект» не так много может сделать, что не относится к другим объектам. ОО работает хорошо, поскольку объектам приказывают изменить свое внутреннее состояние: rectangle.enlarge (margin_in_pixels), но я осознал ограничения несколько лет назад. Однажды мы, программисты, устанавливали оборудование. Кто-то пошутил: "screw.turn" Забавно, но это заставило меня задуматься: конечно, винт может изменить его ориентацию, но это действительно операция между корпусом и винтом; ни один объект не может выполнить задачу сам. ОО просто не достаточно хорош.
ДаренВ

3
+1, после нескольких лет написания "substr (date, 0,4)", трудно написать "date.substring (0,4)"
ern0

4
+1 за фрагмент кода. Это ясно изображает фактический мыслительный процесс.
Картик Сринивасан

2
Я бы на самом деле прочитал это как команду, которую вы посылаете. Как в «Скажи машине повернуть налево». Ооп был основан на отправке сообщений объектам, так что я бы это интерпретировал.
bunglestink

1
Хорошая идея, так может ООП больше подходит для моделирования "систем агентов"?
Qbik

21

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

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

  • важные понятия скрыты за нечетными именами (ФП: Что такое монада? ООП: Почему они иногда называют их функциями, а методы - в других?)

  • странные понятия объясняются в метафоре, а не с точки зрения того, что они на самом деле делают, или почему вы их используете, или почему кто-то когда-либо думал использовать их (FP: Монада - это скафандр, она оборачивает некоторый код. ООП: An объект похож на утку, он может шуметь, ходить и наследовать от животных)

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

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

Позднее небольшие скачки помогают уточнить понимание, но это первый, который берет человека из «ООП не имеет смысла, почему люди делают это?» на "ООП-это лучшее, почему люди делают что-то еще?"


8
Я особенно ненавижу метафоризм, чаще всего они путают, а не описывают.
Ли Райан

3
«Затем у меня были прыжки, как будто я понял, что вызов метода из объекта очень похож на статический вызов с этим объектом в качестве первого параметра». Я хотел бы, чтобы это было подчеркнуто больше с самого начала, как это происходит в таких языках, как Python.
Джаред Апдайк

1
Моя проблема с использованием метафор для объяснения понятий заключается в том, что учитель часто останавливается на метафоре, как будто это объясняет все. Нет, это не полное объяснение; это просто иллюстрация, которая поможет нам обернуть голову вокруг фактического объяснения.
Джоккинг

Отличный ответ! +1 за объяснение того, что первый шаг к пониманию ООП будет более значительным, чем то, что произойдет позже как естественное расширение с хорошим пониманием основы. : D
Картик Сринивасан

то же самое о «скачковом» обучении: когда я начал воспринимать ООП как «просто» модульную / структурированную / пошаговую конструкцию, но на стероидах; когда я переписал несколько очень старых и изуродованных программ на языке COBOL. Несмотря на глобальную область применения COBOL, я по существу применил ОО-принципы с пользовательскими структурами записей, одноцелевыми переменными и строго сфокусированными, модульными и структурированными абзацами (методами).
Радар Боб

15

Потому что основное объяснение ООП очень и очень мало связано с тем, как оно используется в полевых условиях. Большинство программ для обучения этому пытаются использовать физическую модель, такую ​​как «Думайте об автомобиле как об объекте, и о колесах как об объектах, и о дверях, и о трансмиссии ...», но за пределами некоторых неясных случаев программирования на симуляциях, объекты гораздо чаще используются для представления нефизических понятий или для введения косвенности. В результате люди интуитивно понимают это неправильно.

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


13

Я не согласен с ответом Димчи по большей части:

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

  2. Отдельные методы в хороших ОО программах НЕ имеют тенденцию быть процедурными. Это становится все более и более правдоподобным с развитием языков ОО (читай С #, потому что кроме С ++ это единственный другой язык ОО, который я знаю) и их синтаксис, который становится все сложнее с каждым днем ​​(лямбда-выражения, LINQ для объектов и т. Д.). Единственное сходство между ОО-методами и процедурами в процедурных языках - это линейный характер каждого, который, я сомневаюсь, изменится в ближайшее время.

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

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

Чтобы ответить на оригинальный вопрос автора, да, OO - более сложная концепция для понимания, чем процедурное программирование. Это потому, что мы не мыслим с точки зрения свойств и методов объектов реальной жизни. Например, человеческий мозг с трудом воспринимает «TurnOn» как метод телевидения, но рассматривает его как функцию человека, включающего телевизор. Точно так же полиморфизм - это чуждое понятие для человеческого мозга, который обычно видит каждый реальный объект только одним «лицом». Наследование снова не является естественным для нашего мозга. Только то, что я разработчик, не означает, что мой сын будет таким. Вообще говоря, человеческий мозг должен быть обучен овладению ОО, тогда как процедурные языки более естественны для него.


2
+1 - я тоже не думаю, что шаблоны проектирования необходимы для обучения ООП на фундаментальном уровне, вы можете быть хорошим программистом ООП и не знать ни одного шаблона проектирования. С другой стороны, вы склонны видеть, что известные шаблоны проектирования естественным образом появляются у хороших программистов ООП. Шаблоны проектирования всегда открыты, а не придуманы.
Гари Уиллоуби

1
+1 - Отличный ответ. Мне нравится 4-й пункт, который вы заявили. Это правда, что можно быть хорошим программистом ОО, не зная, что такое паттерны дизайна!
Картик Сринивасан

Я согласен с # 4, потому что большинство шаблонов проектирования - это не что иное, как подход жевательной резинки / клейкой ленты, чтобы выразительно кодировать вокруг ограничений языка. В других парадигмах шаблоны проектирования могут быть совершенно разными и основываться на их собственных ограничениях. Я не согласен с 2, LINQ и лямбды по-прежнему выполняются процедурно, они просто обеспечивают аккуратно упакованные абстракции более высокого уровня. Потратьте некоторое значительное время на разработку с динамически типизированным процедурным / функциональным языком, таким как JavaScript, и вы поймете, что я имею в виду.
Эван Плейс

6

Я думаю, что многие программисты испытывают трудности с предварительным проектированием и планированием с самого начала. Даже если кто-то сделает весь дизайн за вас, все еще возможно отойти от принципов ООП. Если я возьму кучу спагетти-кода и дам его в класс, это действительно ООП? Тот, кто не понимает ООП, все еще может программировать на Java. Кроме того, не путайте трудность понимания с нежеланием следовать определенной методологии или не соглашаться с ней.


5

Вы должны читать объекты никогда? Ну, вряд ли когда-либо. (Требуется членство в ACM) Мордехай Бен-Ари, который предполагает, что ООП очень сложно, потому что это не парадигма, которая на самом деле естественна для моделирования чего-либо. (Хотя у меня есть оговорки в отношении этой статьи, потому что неясно, каким критериям он считает, что программа должна удовлетворять, чтобы сказать, что она написана на парадигме ООП, а не на процедурной парадигме с использованием языка ОО.)


5

Объектно-ориентированное программирование само по себе не сложно.

Трудная часть состоит в том, чтобы делать это хорошо. Где разместить разрыв между кодами, чтобы вы могли легко перемещать объекты в общий базовый объект и расширять их позже? Как сделать ваш код доступным для других (расширить классы, перенести в прокси, переопределить метод), не перепрыгивая через это.

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


«Мой личный опыт заключается в том, что требуется много практики, чтобы быть во всех ситуациях, когда вы хотели бы, чтобы вы делали это по-другому, чтобы сделать это достаточно хорошо на этот раз». ООП выглядит как кодифицированный список способов не сделать это неправильно, которые не имеют смысла, пока вы не сделали это неправильно всеми этими способами.
Джаред Апдайк

@ Джаред, не совсем. Сравните это с решением sodukus. Существуют различные приемы, которые вы можете сделать, чтобы решить эту проблему, но требуются время и практика, чтобы сделать это хорошо без возврата.

Если кто-то думает о «общем базовом объекте» как об общем предке, тогда это становится ясным. Это действительно так просто. Трудно понять, потому что есть так много вводящих в заблуждение объяснений людей, пытающихся выглядеть умными.
annoying_squid

4

Я просто смотрел видео Ричарда Фейнмана, в котором рассказывалось о том, как у людей могут возникать совершенно разные методологии, когда они думают - я имею в виду совершенно другое.

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

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

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


+1 Я чувствую то же самое, но есть много толчков в противоположном направлении, в том числе Ruby Mixins ... что заставляет вас понять, что строгий OO не для всех.
Дэн Розенстарк

@ Яр Да, это почти то, что я говорил. Хотя я лично не могу представить себе ничего лучше (а Руби водил меня ОРЕХАМИ за год, когда я им пользовался), я начинаю признавать, что у всех разные взгляды. Может быть, некоторые люди используют осязание или слух, когда думают, а не визуализируют, и ОО просто не дает им понять.
Билл К

Я думаю, что это также помогает поощрять более естественные соглашения об именах. Вам больше не нужно кодировать тип функции в имя функции (например INSTR) - потому что имя привязано к типу (например string::find)
Кен Блум

@Ken, хотя я согласен, я думаю, что это скорее вопрос строгой типизации, чем ОО - у Руби есть ОО, но вы теряете много информации о типах из-за утки - Руби имеет тенденцию просто говорить «отправить (это)» и ожидать Вы должны знать, какой магический метод «это» должен реализовать, чтобы работать.
Билл К

@ Билл, ты прав. Это больше вопрос языков, которые поддерживают общее программирование. Вы можете получить хорошие естественные соглашения об именах с системами модулей и классов типов, такими как Haskell, и в Haskell нет ничего особенного. Если бы у C была перегрузка, вы могли бы получить те же самые родовые имена в C.
Кен Блум

4

Я довольно много занимался программированием на GW-Basic и Turbo Pascal до того, как познакомился с OO, так что изначально он ДЕЙСТВОВАЛ .

Не знаю, так ли это с другими, но для меня это было так: мой мыслительный процесс о программировании был чисто процедурным. Как в случае: «случается то и то, потом происходит то и то» и т. Д. Я никогда не считал переменные и данные чем-то большим, чем мимолетными действующими лицами в потоке программы. Программирование было «потоком действий».

Полагаю, то, что было нелегко понять (как бы глупо это ни выглядело сейчас), заключалось в том, что данные / переменные действительно имеют значение , в более глубоком смысле, чем просто мимолетные актеры в «потоке» программы. Или, говоря по-другому: я продолжал пытаться понять это через то , что происходит , а не через то , что есть , что является реальным ключом к пониманию этого.


Интересная точка зрения. Поскольку я изо всех сил пытаюсь понять масштабные проекты C ++, я думаю, что я противоположен, думая в первую очередь с точки зрения данных, «пути прохождения сигналов» от некоторого «входа» к некоторому «выходу». В то время как я также сделал много Basic и Pascal, мое самое раннее техническое мышление было в электронике.
DarenW

3

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

Из того, что я видел / читал, многие люди (по крайней мере, на форумах) ищут «результат» из ООП. Если вы процедурный программист, который не возвращается и не модифицирует расширение своего кода, вам, вероятно, будет трудно понять преимущества.

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

ИМО, тебе нужно подождать, пока он не «щелкнет», или тебя научит кто-то с реальными знаниями, я не думаю, что ты можешь спешить.


5
Если вы приехали из академической среды, то типы игрушечных программ, которые вы там пишете, действительно кажутся бессмысленными и в ООП. Я начал изучать C в колледже, и это было достаточно легко понять, потому что каждая программа состояла из 1 страницы, менее 100 строк. Затем вы пытаетесь изучить ООП, и для этого требуется весь этот багаж и накладные расходы на объекты, просто чтобы сделать то же самое, и это кажется бессмысленным. Но пока вы не написали программу для множества файлов и нескольких тысяч строк, трудно понять, почему любой стиль программирования полезен.
CodexArcanum

3

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

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

ООП - это абстрагированный способ представления абстракций.

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


2

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

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


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

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

2

Мотивация. Труднее чему-то научиться, когда ты не понимаешь почему, а также, когда ты не можешь посмотреть, что ты сделал, и понять, правильно ли ты это сделал или нет.

Нужны небольшие проекты, которые используют ОО, чтобы делать полезные вещи. Я бы посоветовал просмотреть книгу о шаблонах проектирования и найти книгу, которая, очевидно, полезна и хорошо работает с ОО. (Я использовал Стратегию один раз, когда попробовал. Что-то вроде Flyweight или Singleton было бы плохим выбором, так как это способы использования объектов в целом, а не использования объектов для достижения чего-либо.)


Люди всегда говорят о Синглтоне, но его всегда приглашают на вечеринку. Но это правда, он не OO OO DP.
Дэн Розенстарк

-1

Я думаю, что это зависит от возраста (возраст как показатель опыта) и, что более важно, интереса. Если вы «молодой» (т. Е. Зеленый, возможно) и никогда не думали иначе, это кажется довольно простым. С другой стороны, если вы думаете, что это самая крутая вещь, которую вы когда-либо видели - случилось со мной в возрасте 28 лет или около того - это легко впасть в уныние.

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


1
Оо причуда? Сколько лет вашим ученикам - я подозреваю, что этот «причуда» старше, чем они (первая OO, которую я сделал - я знал, что сделал - была Simula примерно в 1983/4, и Simula не была новичком в тот момент)
Murph

@Murph Это было примерно в 2004-2005 годах, и ученикам было определенно больше 45-50 лет (профессиональные программисты в Iberia).
Дэн Розенстарк

хорошо, я могу видеть, как они могли пропустить начало OO. Но к 2004/5 году мы хорошо разбирались в .NET, который в значительной степени является стеной для OO (-: Есть вещи в разработке, которые можно охарактеризовать как причуды, но те, которые не терпят неудачи, быстро превращаются в хорошие вещи
Murph

1
@ Честно говоря, эти парни были программистами мэйнфреймов, которых они пытались преобразовать в Java. Это был действительно забавный и уникальный опыт (не обычный тариф для моих дней обучения Java). Это является правдой, однако, что они видели много вещей , которые приходят и уходят, но , очевидно , OO больше , чем увлечение. Отдельное примечание: я как бы надеялся, что этот юнит-тестирование превратится в причуду, но теперь я обнаружил, что мне нужно написать множество юнит-тестов ... :)
Дэн Розенстарк

-1

Независимо от того, какую парадигму (ООП, функциональную и т. Д.) Вы выберете, для написания компьютерной программы вам необходимо знать, какие шаги будет выполнять ваша программа.

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

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

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


-1

Как человек, который в настоящее время изучает программирование и имеет некоторые проблемы в этой области, я не думаю, что концепция настолько сложна для понимания, как конкретные реализации этой концепции. Я говорю это потому, что у меня есть идея ООП, и я использую ее в PHP около года, но когда я перехожу к C # и смотрю на использование объектов другими программистами, я обнаружил, что многие люди делают это разными способами. что я просто не понимаю Именно это привело меня к дальнейшему пониманию принципов ООП.

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

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

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

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


1
Пара точек или объектов должна рассматриваться как объект. И расстояние должно быть взято как функция от объекта. Использование объектов не означает, что вы делаете объект из всего.
Гангнус

Как я уже сказал, расстояние было плохим примером. Что касается создания объекта из всего, я имею в виду именно то, что я видел происходящим, а не то, что я на самом деле сделал - чего пока еще нет.
dsimer

Это зависит от языка - в SmallTalk расстояние (и все остальное) является объектом. Но в C # вы упомянули, что это будет плохо.
Гангнус

-2

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

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


-2

Основным прыжком для меня было просто понимание абстрактной концепции ООП. Теперь я очень плохо знаком с программированием в целом. Я программировал от года до полутора лет, поэтому мое знакомство с ООП было связано с Actionscript и Processing. Когда я впервые изучил кодирование Actionscript, его не было в ООП. Я научился кодировать непосредственно в панель «Действия», и таким образом я изучил основные основы программирования (переменные, функции, циклы и т. Д.). Так что я научился делать что-то прямо на сцене во Flash или Processing.

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


Вау, часть этого не имела никакого смысла. «Все было очень абстрактным и трудным для обработки между классами и экземплярами объектов и т. Д. Но языки программирования стали намного легче понять, когда я получил ООП. Но сначала нужно было совершить скачок, чтобы установить эти связи»

-2

Рецепт

Хорошее понимание ООП = Хороший наставник или Хорошие книги или оба + Личный интерес + Практика.

Личный интерес

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

Практика, практика и практика

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

Как говорится, «ничто не заменит трудолюбие и не даст пути к успеху».

Удачи!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.