Почему нет последовательного определения основных понятий для ООП?

12

Я очень новичок в программировании и немного смущен чтением \ слушанием различных соглашений из разных источников:

Есть ли у объектно-ориентированного программирования 4 или 5 концепций?

Как новичок, я понимаю, что это 5 концепций:

  • абстракция
  • наследование
  • Инкапсуляция
  • Полиморфизм
  • модульность

Так почему же я не нашел более «строгого» определения, и, кажется, существует несколько вариантов этих понятий?


источник
7
Может быть, потому что это не похоже на математику (некоторые понятия в CS есть, но я думаю, что ООП не относится к этой категории), поэтому для начала нет строгих определений. Например, насколько важна модульность? Это действительно настолько особенное для ООП, что мы должны упомянуть об этом, или это будет нечто, что произойдет само по себе, если мы правильно применим остальные четыре? Некоторые списки добавляют «иерархию», но действительно ли это что-то особенное или просто следует из наследования и полиморфизма?
Торстен Мюллер
6
Совет: как новый программист, вы не должны зацикливаться на понимании терминологии и теории. Сначала соберите некоторый практический опыт программирования, и станет намного более очевидным, о чем говорят эти люди.
Филипп
9
Другое дело, что ООП меняется со временем. Большое внимание в первые дни C ++ (я знаю, что ООП идет еще дальше) было уделено наследованию и полиморфизму. Сегодняшнее внимание уделяется абстракции и инкапсуляции.
Бент
3
Некоторые интересные обсуждения о недостаточной точности определения ОО можно найти здесь: c2.com/cgi/wiki?NobodyAgreesOnWhatOoIs
Мишель Генрих

Ответы:

26

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

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

Philipp
источник
12

Есть ли в объектно-ориентированном программировании 5 или 4 компонента?

Как уже упоминали другие, «ОО» на самом деле не имеет никаких компонентов , потому что это способ думать о моделировании решений проблем, а не набор инструментов или набор четко определенных процессов.

Как новичок, я понимаю, что это 5 компонентов:

Абстракция, Наследование, Инкапсуляция, Полиморфизм и Модульность?

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

Абстракция, инкапсуляция и модульность связаны не столько с кодом, сколько с тем, как вы смотрите на проблему, как вы пытаетесь понять эту проблему, как вы разрабатываете и структурируете свое решение в коде.

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

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

Например, классические примеры часто ссылаются на сущности , такие как Dog, Cat, Elephant, Seagull, Sharkи т.д. Попавшие в «ОО» часто смотрят на такие примеры и сразу же думать : «О, мне нужен базовый объект под названием Animal» , и они даже могут в конечном итоге с другими промежуточные объекты, такие как Mammalи Amphibianв аккуратной иерархии наследования, с различными атрибутами в каждом.

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

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

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

Бен Коттрелл
источник
2
Акула и лягушка плавают, но один - рыба, другой - амфибия. Я думаю, что этот пример хорошо описывает вашу точку зрения.
RubberDuck
10

Термин «объектная ориентация» был придуман доктором Аланом Кей, поэтому он является авторитетным источником того, что он означает, и он определяет его таким образом :

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

Давайте разберемся с этим:

  • обмен сообщениями («отправка виртуального метода», если вы не знакомы с Smalltalk)
  • государственный процесс должен быть
    • локально сохраняется
    • защищенный
    • скрытый
  • крайняя поздняя привязка всех вещей

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

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

Просто мягкое напоминание о том, что на последней OOPSLA я приложил некоторые усилия, чтобы напомнить всем, что Smalltalk - это не только НЕ синтаксис или библиотека классов, но даже не классы. Мне очень жаль, что я давно ввел термин «объекты» для этой темы, потому что он заставляет многих людей сосредоточиться на меньшей идее.

Основная идея - «обмен сообщениями» - это то, что является ядром Smalltalk / Squeak (и это то, что никогда не было полностью завершено в нашей фазе Xerox PARC). У японцев есть маленькое слово - ma - для «того, что находится между» - возможно, ближайший английский эквивалент - «interstitial». Ключом к созданию великолепных и расширяемых систем является гораздо больше, чем дизайн их модулей, а не их внутренние свойства и поведение. Подумайте об интернете - чтобы жить, он (а) должен позволять множество различных видов идей и реализаций, выходящих за рамки какого-либо единого стандарта, и (б) обеспечивать различные степени безопасной совместимости между этими идеями.

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

Обмен сообщениями является фундаментальным для ОО, как метафора и как механизм.

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

Более «современным» термином для «обмена сообщениями» является «динамическая диспетчеризация метода» или «вызов виртуального метода», но он теряет метафору и фокусируется на механизме.

Итак, есть два способа взглянуть на определение Алана Кея: если вы посмотрите на него, стоящее само по себе, вы можете заметить, что обмен сообщениями - это в основном вызов процедуры с поздней привязкой, а поздняя привязка подразумевает инкапсуляцию, поэтому мы можем заключить, что # 1 и # 2 на самом деле являются избыточными, а OO - все о позднем связывании.

Однако позже он пояснил, что важной вещью является обмен сообщениями, и поэтому мы можем взглянуть на него под другим углом зрения: обмен сообщениями связан с запозданием. Теперь, если бы обмен сообщениями был единственно возможным, тогда №3 был бы тривиально верным: если есть только одна вещь, и эта вещь связана с опозданием, то все вещи связаны с опозданием. И снова, инкапсуляция следует из обмена сообщениями.

Подобные пункты также в On Понимание абстракции данных, Revisited по Уильям Р. Кук , а также его предложение по упрощению, современные определения «объекта» и «объектно - ориентированного» .

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

В Smalltalk-72 не было даже никаких объектов! Были только потоки сообщений, которые были проанализированы, переписаны и перенаправлены. Сначала появились методы (стандартные способы анализа и перенаправления потоков сообщений), затем появились объекты (группы методов, которые разделяют некоторые частные состояния). Наследование появилось намного позже, и классы были введены только как способ поддержки наследования. Если бы исследовательская группа Кея уже знала о прототипах, они, вероятно, никогда бы не представили классы.

Бенджамин Пирс в « Типах и языках программирования» утверждает, что определяющей чертой объектной ориентации является открытая рекурсия .

Итак, по словам Алана Кея, ОО - это все о сообщениях. По словам Уильяма Кука, ОО - это динамическая диспетчеризация методов (что на самом деле одно и то же). По словам Бенджамина Пирса, OO - это все об открытой рекурсии, что в основном означает, что самореференции динамически разрешаются (или, по крайней мере, так думают), или, другими словами, обмениваются сообщениями.

Как вы можете видеть, человек, который придумал термин «ОО», имеет довольно метафизический взгляд на объекты, Кук - довольно прагматичный взгляд, а Пирс - очень строгий математический взгляд. Но важно то, что философ, прагматик и теоретик все согласны! Обмен сообщениями является одним из столпов ОО. Период.

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

Йорг Миттаг
источник
1
@DavidArno Ваш комментарий не является конструктивным вообще. Сам Алан Кей утверждает, что он придумал термин «объект» для этой концепции (хотя, я полагаю, не саму концепцию). Если вы собираетесь противоречить общеизвестному авторитету по этому вопросу, хотя бы напишите более конструктивный комментарий.
Андрес Ф.
1
@DavidArno Кроме того, это ваш голос? Итак, кто-то нашел время, чтобы написать исчерпывающий список различных мнений от известных экспертов о том, что означает ООП, и вы отклонили его, потому что вы не согласны с одним предложением? Oookay.
Андрес Ф.
2
@AndresF. Этот ответ можно резюмировать следующим образом: «Есть две школы: Алана Кея и всех остальных. Потому что первый придумал термин, он автоматически прав, а все, кто с ним не согласен, ошибаются». Это обращение к власти с ошибочным ответом. Таким образом, отрицательный голос.
Давид Арно,
2
На самом деле, этот ответ можно резюмировать так: «Есть три школы мысли, исходящие из трех совершенно разных точек зрения, и никто ни с кем не согласен, на самом деле, они все согласны». Лингвистический прескриптивист сказал бы, что Алан Кей изобрел этот термин, он может сказать, что он означает, и он говорит, что это означает обмен сообщениями. Лингвистический дескриптивист сказал бы: нет, Алан Кей ничего не может сказать, мы должны посмотреть, как на самом деле используется этот термин , и именно это сделал Кук: он изучал языки, которые обычно называют ОО (Java, C ++ , C # и т. Д.) Общего, и он нашел
Йорг W Mittag
3
одна вещь: обмен сообщениями. Он изучил то, чего не хватает в языках, которые обычно называют ОО, а в языках, которые обычно называют ОО, и обнаружил одну вещь: обмен сообщениями. Теоретик башни из слоновой кости берет λ-исчисление и смотрит, какой наименьший набор функций нужно добавить, чтобы получить что-то, что обычно называют ОО, и он приходит к открытой рекурсии , которая является в основном строительным блоком для обмена сообщениями. ,
Йорг Миттаг
3

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

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

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

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


Я не вступаю в дискуссию о другом 4 атрибуте и о том, являются ли (например) какие модели «наследования» чистыми ОО. Кроме того, хотя Алану Кей приписывают изобретение ОО-программирования, это не обязательно означает, что его определения ОО / и ООПЛ имеют первенство. Понятно, что это не так. Он авторитетный источник, но есть и другие источники , которые дают другие определения для ОО и OOPLs , что (на практике) нести больший вес.

Стивен С
источник
2
+1 Модульность фактически широко принята как желательный атрибут большинства программных систем, независимо от используемого языка программирования и парадигмы. Многие языки, которые не являются OO, поддерживают модульность.
Андрес Ф.
+1 @AndresF. комментарий. Действительно, «структурированное программирование» и «пошаговое уточнение» (техника для размышления о структуре кода) происходит из тигля «возрастающей сложности, приводящей к еще худшему программному обеспечению». Если бы это предшествовало COBOL, то у языка не было бы такой негативной репутации ИМХО. И я рассматриваю ОО прагматически как просто структуру более высокого порядка. И я имею в виду, что без базовой структуры OO не лучше, чем худший COBOL.
Радар Боб