Когда я начал использовать объектно-ориентированный язык (Java), я просто стал «крутым» и начал писать код. Я никогда не задумывался об этом до недавнего времени, прочитав много вопросов об ООП. Общее впечатление, которое я получаю, это то, что люди борются с этим. Поскольку я не думал об этом как о сложном, и я не сказал бы, что я какой-то гений, я думаю, что, должно быть, что-то упустил или неправильно понял.
Почему ООП трудно понять? Это сложно понять?
object-oriented
gablin
источник
источник
Ответы:
Мне лично было легко понять механику ООП. Трудной частью для меня было «почему». Когда я впервые столкнулся с этим, мне показалось, что это решение проблемы. Вот несколько причин, почему я думаю, что большинству людей это трудно:
ИМХО преподавание ОО с самого начала - ужасная идея. Процедурное кодирование не является «плохой привычкой» и является подходящим инструментом для некоторых рабочих мест. В любом случае отдельные методы в ОО-программе выглядят довольно процедурно. Кроме того, прежде чем изучать процедурное программирование достаточно хорошо, чтобы его ограничения стали видимыми, ОО не кажется студенту очень полезным.
Прежде чем вы действительно сможете понять ОО, вам необходимо знать основы структур данных и функций позднего связывания / высшего порядка. Трудно уловить полиморфизм (который в основном передает указатель на данные и набор функций, которые работают с данными), если вы даже не понимаете концепции структурирования данных вместо того, чтобы просто использовать примитивы и передавать функции более высокого порядка / указатели на функции.
Шаблоны проектирования должны преподаваться как нечто фундаментальное для ОО, а не как нечто более продвинутое. Шаблоны проектирования помогают вам видеть лес сквозь деревья и дают относительно конкретные примеры того, как ОО может упростить реальные проблемы, и вы в любом случае захотите их изучить. Кроме того, как только вы действительно получаете ОО, большинство шаблонов проектирования становятся очевидными задним числом.
источник
Cat
классе, который наследуетсяMammal
, использовать реальный пример из реальной программы, которую мы написали бы процедурно. Как простая структура данных.Я думаю, что есть несколько факторов, которые еще не были упомянуты.
Прежде всего, по крайней мере, в «чистом ООП» (например, Smalltalk), где все является объектом, вы должны изогнуть свой ум в довольно неестественную конфигурацию, чтобы думать о числе (только для одного примера) как об интеллектуальном объекте вместо просто значение - поскольку в действительности
21
(например) действительно является просто значением. Это становится особенно проблематичным, когда, с одной стороны, вам говорят, что большим преимуществом ООП является более точное моделирование реальности, но вы начинаете с того, что очень похоже на ЛСД-вдохновленный взгляд даже на самые простые и очевидные части реальность.Во-вторых, наследование в ООП также не очень близко следует ментальным моделям большинства людей. Для большинства людей, классификация вещей наиболее конкретно не имеет где-либо близко к абсолютным правилам, необходимым для создания иерархии классов, которая работает. В частности, создание того,
class D
что наследует от другого,class B
означает, что объектыclass D
разделяют абсолютно все положительные характеристикиclass B
.class D
Можно добавлять новые и разные характеристики самостоятельно, но все характеристикиclass B
должны оставаться неизменными.Напротив, когда люди классифицируют вещи мысленно, они обычно следуют гораздо более слабой модели. Для одного примера, если человек устанавливает некоторые правила относительно того, что составляет класс объектов, довольно типично, что почти любое одно правило может быть нарушено при условии соблюдения достаточного количества других правил. Даже те немногие правила, которые не могут быть нарушены, почти всегда могут быть немного растянуты.
Просто для примера рассмотрим "автомобиль" как класс. Довольно легко увидеть, что подавляющее большинство того, что большинство людей считает «автомобилями», имеют четыре колеса. Большинство людей, однако, видели (по крайней мере, изображение) автомобиль только с тремя колесами. Некоторые из нас нужного возраста также помнят гоночный автомобиль или два из ранних 80-х (или около того), которые имели шесть колес - и так далее. Это оставляет нам в основном три варианта:
Преподавание ООП часто фокусируется на построении огромных таксономий - например, кусочков того, что будет гигантской иерархией всей известной жизни на земле, или чего-то подобного. Это поднимает две проблемы: во-первых, это приводит к тому, что многие люди сосредотачиваются на огромных объемах информации, которая совершенно не имеет отношения к рассматриваемому вопросу. В какой-то момент я увидел довольно продолжительное обсуждение того, как моделировать породы собак, и должен ли (например) «миниатюрный пудель» наследоваться от «полноразмерного пуделя», или наоборот, или должна быть абстрактная основа «пудель». "class, с" полноразмерным пуделем "и" миниатюрным пуделем ", оба наследуют от него. То, что они все, казалось, игнорировали, было то, что приложение должно было иметь дело с отслеживанием лицензий для собак,
Во-вторых, и это почти важно, это приводит к фокусированию на характеристиках предметов, а не на характеристиках, которые важны для стоящей перед нами задачи. Это ведет к моделированию вещей такими, какие они есть, где (в большинстве случаев) действительно необходимо построить простейшую модель, которая будет удовлетворять наши потребности, и использовать абстракцию для подбора необходимых подклассов, чтобы соответствовать построенной нами абстракции.
Наконец, я еще раз скажу: мы медленно идем тем же путем, по которому базы данных шли годами. Ранние базы данных следовали иерархической модели. Помимо сосредоточения исключительно на данных, это единственное наследование. В течение короткого времени несколько баз данных следовали сетевой модели - по существу, идентичной множественному наследованию (и с этой точки зрения, несколько интерфейсов недостаточно отличаются от множества базовых классов, чтобы замечать или заботиться о них).
Однако давно базы данных в значительной степени сходились по реляционной модели (и хотя они не являются SQL, на этом уровне абстракции текущие базы данных «NoSQL» также являются реляционными). Преимущества реляционной модели достаточно хорошо известны, поэтому я не буду повторять их здесь. Я просто отмечу, что наиболее близким аналогом реляционной модели, которую мы имеем в программировании, является универсальное программирование (и извините, но, несмотря на название, дженерики Java, например, на самом деле не подходят, хотя они представляют собой крошечный шаг в правильное направление).
источник
ООП требует умения мыслить абстрактно; дар / проклятие, которое на самом деле имеют немногие люди, даже профессиональные программисты.
источник
Я думаю, что вы можете обобщить основные трудности следующим образом:
Конечно, люди могут привыкнуть к отображению «левого» как 270, и да, сказать «Car.Turn» вместо «Turn the Car» не такой большой скачок. НО, чтобы хорошо разбираться с этими объектами и создавать их, вы должны обратить то, что вы обычно думаете.
Вместо того, чтобы манипулировать объектом, мы говорим, чтобы объект действительно делал вещи самостоятельно. Это может больше не чувствовать затруднения, но говорить о том, что окно открывается само по себе, звучит странно. Люди, не привыкшие к такому мышлению, вынуждены снова и снова бороться с этой странностью, пока, наконец, она не станет естественной.
источник
Любая парадигма требует определенного толчка «через край», чтобы понять, для большинства людей. По определению, это новый способ мышления, и поэтому требуется определенное количество отпусков старых понятий и определенное понимание того, почему новые понятия полезны.
Я думаю, что большая проблема в том, что методы, используемые для обучения компьютерному программированию, в целом довольно плохие. ООП настолько распространен сейчас, что это не так заметно, но вы все еще часто видите его в функциональном программировании:
важные понятия скрыты за нечетными именами (ФП: Что такое монада? ООП: Почему они иногда называют их функциями, а методы - в других?)
странные понятия объясняются в метафоре, а не с точки зрения того, что они на самом деле делают, или почему вы их используете, или почему кто-то когда-либо думал использовать их (FP: Монада - это скафандр, она оборачивает некоторый код. ООП: An объект похож на утку, он может шуметь, ходить и наследовать от животных)
хорошие вещи варьируются от человека к человеку, поэтому не совсем ясно, что станет переломным моментом для любого ученика, и часто учитель даже не может вспомнить. (ФП: О, монады позволяют вам скрывать что-то в самом типе и продолжать его без необходимости явно записывать, что происходит каждый раз. ООП: О, объекты позволяют вам сохранять функции для своего рода данных с этими данными.)
Хуже всего то, что, как показывает вопрос, некоторые люди сразу же поймут, почему концепция хороша, а некоторые нет. Это действительно зависит от того, что является переломным моментом. Для меня понимание того, что объекты хранят данные и методы для этих данных, было ключевым, после этого все остальное просто подходило как естественное расширение. Затем у меня были прыжки, как будто я понял, что вызов метода из объекта очень похож на статический вызов с этим объектом в качестве первого параметра.
Позднее небольшие скачки помогают уточнить понимание, но это первый, который берет человека из «ООП не имеет смысла, почему люди делают это?» на "ООП-это лучшее, почему люди делают что-то еще?"
источник
Потому что основное объяснение ООП очень и очень мало связано с тем, как оно используется в полевых условиях. Большинство программ для обучения этому пытаются использовать физическую модель, такую как «Думайте об автомобиле как об объекте, и о колесах как об объектах, и о дверях, и о трансмиссии ...», но за пределами некоторых неясных случаев программирования на симуляциях, объекты гораздо чаще используются для представления нефизических понятий или для введения косвенности. В результате люди интуитивно понимают это неправильно.
Обучение на основе шаблонов проектирования - это гораздо лучший способ описания ООП, поскольку оно показывает программистам, как некоторые реальные проблемы моделирования можно эффективно атаковать объектами, а не описывать их абстрактно.
источник
Я не согласен с ответом Димчи по большей части:
Обучение ОО с самого начала не является плохой идеей внутри самого себя, равно как и обучение процедурным языкам. Важно то, что мы учим людей писать ясный, лаконичный, связный код, независимо от того, какой он является ОО или процедурным.
Отдельные методы в хороших ОО программах НЕ имеют тенденцию быть процедурными. Это становится все более и более правдоподобным с развитием языков ОО (читай С #, потому что кроме С ++ это единственный другой язык ОО, который я знаю) и их синтаксис, который становится все сложнее с каждым днем (лямбда-выражения, LINQ для объектов и т. Д.). Единственное сходство между ОО-методами и процедурами в процедурных языках - это линейный характер каждого, который, я сомневаюсь, изменится в ближайшее время.
Вы не можете овладеть процедурным языком без понимания структуры данных. Концепция указателя так же важна для процедурных языков, как и для ОО-языков. Например, передача параметров по ссылке, что довольно часто встречается в процедурных языках, требует от вас понимания указателей настолько, насколько это необходимо для изучения любого языка ОО.
Я не думаю, что шаблоны проектирования должны преподаваться на ранних этапах ОО-программирования вообще, потому что они не являются фундаментальными для ОО-программирования вообще. Определенно можно быть хорошим программистом ОО, не зная ничего о шаблонах проектирования. Фактически, человек может даже использовать известные шаблоны проектирования, даже не зная, что они задокументированы как таковые с собственными именами и что о них написаны книги. То, чему следует научить, - это принципы проектирования, такие как единая ответственность, открытое закрытие и разделение интерфейса. К сожалению, многие люди, которые считают себя ОО-программистами в наши дни, либо не знакомы с этой фундаментальной концепцией, либо просто игнорируют ее, и поэтому у нас так много мусорного ОО-кода.
Чтобы ответить на оригинальный вопрос автора, да, OO - более сложная концепция для понимания, чем процедурное программирование. Это потому, что мы не мыслим с точки зрения свойств и методов объектов реальной жизни. Например, человеческий мозг с трудом воспринимает «TurnOn» как метод телевидения, но рассматривает его как функцию человека, включающего телевизор. Точно так же полиморфизм - это чуждое понятие для человеческого мозга, который обычно видит каждый реальный объект только одним «лицом». Наследование снова не является естественным для нашего мозга. Только то, что я разработчик, не означает, что мой сын будет таким. Вообще говоря, человеческий мозг должен быть обучен овладению ОО, тогда как процедурные языки более естественны для него.
источник
Я думаю, что многие программисты испытывают трудности с предварительным проектированием и планированием с самого начала. Даже если кто-то сделает весь дизайн за вас, все еще возможно отойти от принципов ООП. Если я возьму кучу спагетти-кода и дам его в класс, это действительно ООП? Тот, кто не понимает ООП, все еще может программировать на Java. Кроме того, не путайте трудность понимания с нежеланием следовать определенной методологии или не соглашаться с ней.
источник
Вы должны читать объекты никогда? Ну, вряд ли когда-либо. (Требуется членство в ACM) Мордехай Бен-Ари, который предполагает, что ООП очень сложно, потому что это не парадигма, которая на самом деле естественна для моделирования чего-либо. (Хотя у меня есть оговорки в отношении этой статьи, потому что неясно, каким критериям он считает, что программа должна удовлетворять, чтобы сказать, что она написана на парадигме ООП, а не на процедурной парадигме с использованием языка ОО.)
источник
Объектно-ориентированное программирование само по себе не сложно.
Трудная часть состоит в том, чтобы делать это хорошо. Где разместить разрыв между кодами, чтобы вы могли легко перемещать объекты в общий базовый объект и расширять их позже? Как сделать ваш код доступным для других (расширить классы, перенести в прокси, переопределить метод), не перепрыгивая через это.
Это трудная часть, и если все сделано правильно, это может быть очень элегантно, а если сделано плохо, может быть очень неуклюжим. Мой личный опыт показывает, что требуется много практики, чтобы быть во всех ситуациях, когда вы хотели бы, чтобы вы делали это по-другому, чтобы сделать это достаточно хорошо на этот раз.
источник
Я просто смотрел видео Ричарда Фейнмана, в котором рассказывалось о том, как у людей могут возникать совершенно разные методологии, когда они думают - я имею в виду совершенно другое.
Когда я занимаюсь проектированием высокого уровня, мне приходится визуализировать объекты, я вижу их, вижу их интерфейсы и вижу, по каким путям должна пройти информация.
У меня также возникают проблемы с запоминанием деталей, и я обнаружил, что ОО является отличной организационной помощью - гораздо проще найти функциональность, чем сканирование по плохо организованному списку подпрограмм.
Для меня ОО был большим преимуществом, но если вы не визуализируете то же самое или не делаете высокоуровневую архитектуру, это, вероятно, бессмысленно и раздражает.
источник
INSTR
) - потому что имя привязано к типу (напримерstring::find
)Я довольно много занимался программированием на GW-Basic и Turbo Pascal до того, как познакомился с OO, так что изначально он ДЕЙСТВОВАЛ .
Не знаю, так ли это с другими, но для меня это было так: мой мыслительный процесс о программировании был чисто процедурным. Как в случае: «случается то и то, потом происходит то и то» и т. Д. Я никогда не считал переменные и данные чем-то большим, чем мимолетными действующими лицами в потоке программы. Программирование было «потоком действий».
Полагаю, то, что было нелегко понять (как бы глупо это ни выглядело сейчас), заключалось в том, что данные / переменные действительно имеют значение , в более глубоком смысле, чем просто мимолетные актеры в «потоке» программы. Или, говоря по-другому: я продолжал пытаться понять это через то , что происходит , а не через то , что есть , что является реальным ключом к пониманию этого.
источник
Я не думаю, что это трудно понять, но может случиться так, что многие программисты, опрашивающие, являются новыми для этой концепции, происходящими из процедурных языков.
Из того, что я видел / читал, многие люди (по крайней мере, на форумах) ищут «результат» из ООП. Если вы процедурный программист, который не возвращается и не модифицирует расширение своего кода, вам, вероятно, будет трудно понять преимущества.
Кроме того, существует много плохих ООП, если люди читают / видят это, то легко понять, почему им может быть трудно.
ИМО, тебе нужно подождать, пока он не «щелкнет», или тебя научит кто-то с реальными знаниями, я не думаю, что ты можешь спешить.
источник
Я думаю, что причина ООП сложна для многих в том, что инструменты на самом деле не способствуют этому.
Компьютерные языки сегодня являются абстракцией того, что происходит в компьютере.
ООП - это абстрагированный способ представления абстракций.
Поэтому мы используем абстракцию для создания абстракций с абстракцией. Добавьте к этому, что то, что мы абстрагируем, это обычно очень сложные физические / социальные взаимодействия и, что ж, неудивительно.
источник
На самом деле у меня есть блог под названием «Борьба в объектно-ориентированном программировании», который родился в результате некоторых моих трудностей с его изучением. Я думаю, что это было особенно трудно для меня понять, потому что я потратил так много времени, используя процедурное программирование, и мне было тяжело прийти в голову, что объект может быть представлен набором атрибутов и поведений (я привык к просто набор переменных и методов).
Кроме того, существует множество концепций, которые делают объектно-ориентированный язык - наследованием, интерфейсами, полиморфизмом, композицией и т. Д. В теории очень много нужно узнать, прежде чем вы действительно сможете эффективно писать код и в объектно-ориентированном виде. Кстати, тогда как при процедурном программировании это просто вопрос понимания таких вещей, как распределение памяти для переменных и вызовы точек входа для других методов.
источник
Мотивация. Труднее чему-то научиться, когда ты не понимаешь почему, а также, когда ты не можешь посмотреть, что ты сделал, и понять, правильно ли ты это сделал или нет.
Нужны небольшие проекты, которые используют ОО, чтобы делать полезные вещи. Я бы посоветовал просмотреть книгу о шаблонах проектирования и найти книгу, которая, очевидно, полезна и хорошо работает с ОО. (Я использовал Стратегию один раз, когда попробовал. Что-то вроде Flyweight или Singleton было бы плохим выбором, так как это способы использования объектов в целом, а не использования объектов для достижения чего-либо.)
источник
Я думаю, что это зависит от возраста (возраст как показатель опыта) и, что более важно, интереса. Если вы «молодой» (т. Е. Зеленый, возможно) и никогда не думали иначе, это кажется довольно простым. С другой стороны, если вы думаете, что это самая крутая вещь, которую вы когда-либо видели - случилось со мной в возрасте 28 лет или около того - это легко впасть в уныние.
С другой стороны, если вы думаете, как это делали многие из моих учеников по Java, «почему мы учимся этому, это просто увлечение», то учиться практически невозможно. Это верно для большинства технологий.
источник
Независимо от того, какую парадигму (ООП, функциональную и т. Д.) Вы выберете, для написания компьютерной программы вам необходимо знать, какие шаги будет выполнять ваша программа.
Естественным способом определения процесса является запись его шагов, для больших задач вы разбиваете задачу на более мелкие шаги. Это процедурный способ, это то, как работает компьютер, это то, как вы шаг за шагом просматриваете свой контрольный список.
ООП - это другой способ мышления. Вместо того, чтобы думать о контрольном списке задач, которые нужно выполнять шаг за шагом, вы думаете об объектах, их способностях и отношениях. Таким образом, вы напишите много объектов, небольшие методы, и ваша программа будет волшебным образом работать. Чтобы добиться этого, вам нужно закрутить свой разум ...
И именно поэтому ООП сложно. Поскольку все является объектом, все, что они делают, - это просят, чтобы другие объекты что-то сделали, а те другие объекты в основном делают что-то. Таким образом, элемент управления в программе ООП может дико перепрыгивать между объектами.
источник
Как человек, который в настоящее время изучает программирование и имеет некоторые проблемы в этой области, я не думаю, что концепция настолько сложна для понимания, как конкретные реализации этой концепции. Я говорю это потому, что у меня есть идея ООП, и я использую ее в PHP около года, но когда я перехожу к C # и смотрю на использование объектов другими программистами, я обнаружил, что многие люди делают это разными способами. что я просто не понимаю Именно это привело меня к дальнейшему пониманию принципов ООП.
Конечно, я понимаю, что проблема, скорее всего, заключается в том, что у меня нет опыта работы с языком, изначально имеющим ООП, и что со временем я найду новые способы использования объектов, которые будут столь же неясны для нового программиста, как и я. в настоящее время испытываю. Джерри Коффин затрагивает это несколько раз, особенно в своем комментарии:
Я нахожу это очень точным, так как это впечатление, которое я часто испытываю, когда вижу, как кто-то создает классы для вещей, которые на самом деле не являются вещами - конкретный пример ускользает от меня, но самое близкое, что я могу придумать на лету, это трактовать расстояние как объект (я отредактирую в следующий раз, когда увижу что-то, что вызывает такую же путаницу). Временами ООП, кажется, временно игнорирует свои собственные правила и становится менее интуитивным. Это чаще всего происходит, когда объекты создают объекты, наследуются от класса, который их инкапсулирует, и так далее.
Я думаю, что для кого-то, как я, это помогает думать о концепции объектов как о множественных гранях, одна из которых включает в себя обработку чего-то похожего на объект, в противном случае это не так. Нечто подобное расстоянию, с небольшим изменением парадигмы, может показаться теоретическим объектом, но не тем, что можно держать в руке. Я должен думать о нем как о наборе свойств, но о более абстрактном наборе поведений, например, о доступе к его свойствам. Я не уверен, что это является ключом к моему пониманию, но, похоже, именно туда ведут мои нынешние исследования.
источник
Терминологии были моим ударом в дороге при изучении принципов объектно-ориентированного программирования (POOP). Это когда вы понимаете основы, части начинают становиться на свои места. Как и все вещи, изучение новых понятий немного сложно.
Согласились с тем, что шаблоны проектирования следует рассматривать как минимум параллельно ООП.
источник
Основным прыжком для меня было просто понимание абстрактной концепции ООП. Теперь я очень плохо знаком с программированием в целом. Я программировал от года до полутора лет, поэтому мое знакомство с ООП было связано с Actionscript и Processing. Когда я впервые изучил кодирование Actionscript, его не было в ООП. Я научился кодировать непосредственно в панель «Действия», и таким образом я изучил основные основы программирования (переменные, функции, циклы и т. Д.). Так что я научился делать что-то прямо на сцене во Flash или Processing.
Когда ООП пришел в себя, я понял, что сначала я могу создать методы и свойства внутри объекта, чтобы их можно было использовать и использовать повторно. Все было очень абстрактным и трудным для обработки, но сами языки программирования были намного лучше, но сначала понадобился прыжок веры, чтобы установить эти связи.
источник
Рецепт
Хорошее понимание ООП = Хороший наставник или Хорошие книги или оба + Личный интерес + Практика.
Личный интерес
Исходя из моего личного опыта, личный интерес проходит долгий путь, чтобы перейти от процедурного программирования к ООП с правильными вкладами наставников или хороших книг или обоих вместе взятых .
Практика, практика и практика
Мой лучший друг, чтобы лучше понять ООП - это не что иное, как практика. Это определенно будет способствовать вашим способностям ООП.
Как говорится, «ничто не заменит трудолюбие и не даст пути к успеху».
Удачи!
источник