Нужны ли нам языки OO для управления сложностью программного обеспечения?

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

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

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

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

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

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

206 голосов | спросил steakexchange 20 MarpmMon, 20 Mar 2017 13:13:40 +03002017-03-20T13:13:40+03:0001 2017, 13:13:40

16 ответов


176

Позвольте мне попробовать с очень низким теоретическим ответом:)

Что вы действительно спрашиваете: Зачем включать поддержку Ориентации объектов (OO) непосредственно на языке, когда процедурные языки могут использоваться для проектирования и записи OO-кода?

И ответ: Чтобы иметь стандарт для того, как OO выражается в исходном коде, поэтому вы не получаете 22 разных реализаций для той же абстракции.

Например, скажем, я создаю MagicButton и MagicSlider, которые можно использовать в системе пользовательского интерфейса. Мне нужен способ группировать методы, которые можно использовать с MagicButton, методы, которые могут использоваться только с MagicSlider, и методы, которые могут использоваться обоими. Эти объекты используют некоторые методы, потому что они оба являются объектами Magic gui.

Я могу выполнять группировку с помощью функций именования специальным способом MagicSlider_DoSomething ..., включая методы в определенных файлах, названных по-особому MagicSliderMethods.XXX, или я мог бы найти какой-то другой способ сделать то же самое. Если на этом языке нет стандартного способа, я сделаю это иначе, чем вы, и иначе, чем кто-либо другой. Это делает код обмена намного сложнее.

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

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

Также: наличие абстракций в языке позволяет расширенным редакторам кода, таким как Eclipse, делать много статического анализа кода. Например, Eclipse может предложить список всех методов, которые могут быть использованы для объекта, а также автоматическая реализация пустых «методов TODO». Eclispe точно знает, какие методы должен выполнять ваш класс на основе того, какие классы вы расширяете, и какие интерфейсы вы реализуете. Это было бы почти невозможно, если бы не было языкового стандарта для выполнения OO.

ответил MTilsted 20 MarpmMon, 20 Mar 2017 18:32:23 +03002017-03-20T18:32:23+03:0006 2017, 18:32:23
209
  

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

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

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

Например, одна из основных работ по модульности - О критериях, которые будут использоваться в системах разложения в модулях . Там нет упоминания ОО. (Это было написано в 1972 году, к тому времени ОО по-прежнему оставалась неясной нишей, несмотря на то, что ей уже более десяти лет.)

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

  • С абстрактными типами данных механизм абстракции представляет собой систему типов ; это система типов, которая скрывает реализацию. (Тип системы необязательно должен быть статичным.) С объектами реализация скрыта за процедурным интерфейсом , который не требует типов. (Например, он может быть реализован с помощью закрытий, как это сделано в ECMAScript.)
  • С абстрактными типами данных экземпляры разных ADT инкапсулированы друг в друга, но экземпляры ADT same могут проверять и просматривать представление и частную реализацию друг друга. Объекты всегда заключены в все . Только сам объект может проверять собственное представление и получать доступ к его собственной частной реализации. Нет другого объекта , даже другие объекты того же типа, другие экземпляры одного и того же класса, другие объекты, имеющие один и тот же прототип, клоны объекта или что-то еще. None .

Что это значит, кстати, это то, что в Java классы не являются объектно-ориентированными. Два экземпляра одного класса могут получать доступ к представлению и частной реализации друг друга. Поэтому экземпляры классов не являются объектами, они фактически являются экземплярами ADT. Java interface s, однако do обеспечивает объектно-ориентированную абстракцию данных. Итак, другими словами: только экземпляры интерфейсов являются объектами в Java, экземпляры классов не являются.

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

  

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

То, что вы описываете , OO.

Это действительно хороший способ подумать о OO. Фактически, это в значительной степени то, что имели в виду оригинальные изобретатели ОО. (Алан Кей сделал еще один шаг: он представил множество маленьких компьютеров, отправляющих сообщения друг другу по сети.) То, что вы называете «программой», обычно называют «объектом», а вместо «вызова» мы обычно говорим «отправить сообщение» ».

Ориентация объектов - это Обмен сообщениями (aka динамическая отправка ). Термин «объектно-ориентированный» был придуман д-ром Аланом Кей, главным дизайнером Smalltalk, и он определяет это следующим образом:

  

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

Давайте сломаем этовниз:

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

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

Позже он пояснил, что « Большая идея - messaging ' ", и сожалеет, что назвал его« объектно-ориентированным », а не« ориентированным на сообщения », потому что термин« объектно-ориентированный »ставит фокус на несущественную вещь (объекты) и отвлекает от того, что на самом деле важный (обмен сообщениями):

  

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

     

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

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

Сообщения basic для OO, как метафоры, так и как механизм.

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

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

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

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

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

  

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

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

Бенджамин Пирс в Типы и языки программирования утверждает, что определяющая особенность Object-Orientation Open Recursion .

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

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

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

ответил Jörg W Mittag 20 MarpmMon, 20 Mar 2017 14:18:36 +03002017-03-20T14:18:36+03:0002 2017, 14:18:36
66
  

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

Когда вы говорите «очень легко», вы делаете очень смелое заявление. То, как я читаю, это: «Я не вижу трудности, поэтому она не должна быть очень большой». Когда формулируется именно так, становится ясно, что вы не спрашиваете: «зачем нам нужно OO», вы спрашиваете: «Почему не трудности, с которыми сталкиваются другие парадигмы программирования, которые приводят к очевидному явлению OO сразу? «

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

Для многих видов игрушечных программ студентам CS поручено писать, мы могли бы также писать их на BASIC или сборке как Java или Python. Это связано с тем, что присущая сложность задач настолько мала, что есть только один разработчик, нет проблем с совместимостью с предыдущими версиями, производительность не имеет значения, и код, скорее всего, когда-нибудь будет выполняться несколько раз на одной машине.

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

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

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

Квалифицированный, достаточно дисциплинированный программист действительно может создать функционирующую систему с высокой степенью сложности в C или сборке. Но мы не все Линус Торвальдс. Мы также не должны быть, чтобы создать полезное программное обеспечение.

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

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

ответил Clement Cherlin 20 MarpmMon, 20 Mar 2017 18:29:37 +03002017-03-20T18:29:37+03:0006 2017, 18:29:37
22

То, что вы описываете, не OOP, это абстракция. Абстракция присутствует во всех современных моделях дизайна, даже тех, которые не являются ООП. И ООП - это очень специфический вид абстракции.

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

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

Однако, вот некоторые способы ООП более тонкие, чем то, что вы сказали:

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

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

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

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

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

ответил jmite 20 MaramMon, 20 Mar 2017 08:54:39 +03002017-03-20T08:54:39+03:0008 2017, 08:54:39
11
  

Нужны ли нам языки OO для управления сложностью программного обеспечения?

Это зависит от значения слова «потребность».

Если требуется «необходимость», мы не требуем этого.

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

Большое изображение

Языки OO связывают функциональность с данными.

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

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

И действительно, это все вызовы методов: частичные функции на связанных наборах данных.

Функция по функции

Особенности OOP:

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

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

Ссылки

Есть много критиков ООП .

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

Заключение

Мы не нуждаемся в ООП. Но в некоторых случаях пользователь хочет OOP.

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

ответил Aaron Hall 20 MarpmMon, 20 Mar 2017 23:01:44 +03002017-03-20T23:01:44+03:0011 2017, 23:01:44
10

Я постараюсь быть кратким.

Основным принципом OO является комбинация данных и поведения в единой организационной единице (объекте).

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

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

Итак, да, OO - это большое дело. И нет, это не просто куча старых вещей с причудливым именем.

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

ответил Martin Maat 21 MaramTue, 21 Mar 2017 01:53:07 +03002017-03-21T01:53:07+03:0001 2017, 01:53:07
8

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

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

  

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

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

ответил JacquesB 20 MarpmMon, 20 Mar 2017 21:42:52 +03002017-03-20T21:42:52+03:0009 2017, 21:42:52
7

Что-то, о чем не говорили другие ответы: state.

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

Что я думаю , о котором мы говорим, это сложность, связанная с состоянием.

Есть две основные идеи в инкапсуляции . Один из них, скрытие деталей реализации , довольно хорошо освещен в других ответах. Но другой скрывает свое состояние времени выполнения . Мы не обманываем внутренними данными объектов; мы передаем сообщения (или вызываем методы, если вы предпочитаете детали реализации над концепцией, как указал Jörg Mittag). Почему?

Люди уже упомянули об этом, потому что вы не можете изменить внутреннюю структуру своих данных, не меняя код, к которому он обращается, и вы хотите сделать это в одном месте (метод доступа) вместо 300 мест.

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

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

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

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

ответил Jared Smith 21 MarpmTue, 21 Mar 2017 18:12:02 +03002017-03-21T18:12:02+03:0006 2017, 18:12:02
5
  

Нам действительно нужны языки OO для управления сложностью программного обеспечения?

Нет. Но они могут помочь во многих ситуациях.

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

Например, приложение Windows, использующее оригинальный низкоуровневый API Windows для отображения формы, кнопки и поля редактирования, требует большого количества кода, а вместо этого использует библиотеки объектов, которые поставляются с Visual Basic или C # или Delphi сделать ту же программу крошечной и тривиальной. Таким образом, мой код OO обычно относительно невелик и для графического интерфейса, в то время как мой код, вызываемый этими объектами, обычно намного больше и обычно не связан с OO (хотя он может меняться в зависимости от проблемы, которую я пытаюсь решить).

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

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

ответил joe snyder 20 MarpmMon, 20 Mar 2017 23:16:37 +03002017-03-20T23:16:37+03:0011 2017, 23:16:37
3

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

Модульность важна. Но модульность может быть реализована практически на любом достойном языке. Например, C поддерживает модульную компиляцию, файлы заголовков и типы структуры. Этого достаточно для 99% случаев. Определите модуль для каждого нового абстрактного типа данных, который вам нужен, и определите функции для работы с типом данных. Иногда вы хотите, чтобы производительность и эти функции находились в файле заголовка в виде встроенных функций, в других случаях вы будете использовать стандартные функции. Для пользователя все невидимо, какой путь выбран.

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

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

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

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

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

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

ответил juhist 22 MarpmWed, 22 Mar 2017 18:49:30 +03002017-03-22T18:49:30+03:0006 2017, 18:49:30
2

Причиной внедрения парадигм программирования, включая объектно-ориентированные методы, является упрощение создания более сложных и мощных программ. В выпуске журнала Byte за август 1981 года Daniel Ingalls , один из ключевых создателей Smalltalk, определил «объектно-ориентированный» как имеющий следующие возможности:

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

Это были принципы, которые Ингаллс определил как соображения для проектирования для SmallTalk-80, разработанные Xerox Parc Research. В вышеупомянутой статье журнала вы можете прочитать подробное описание каждого из этих принципов и то, как они вносят вклад в объектно-ориентированную парадигму согласно Ингаллсу.

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

Например, чтобы взять первый из принципов Ingall (автоматическое управление хранением), любой может написать свою собственную систему управления автоматическим хранением на процедурный язык, но для этого было бы очень много работы. При использовании языка, такого как SmallTalk или Java, на котором встроено автоматическое управление хранением данных, программисту не нужно делать столько работы, управляя памятью. Компромисс заключается в том, что программист получает меньше контроля над тем, как используется память. Таким образом, есть преимущество и недостаток. Идея дизайнерской парадигмы, такой как объектно-ориентированное программирование, заключается в том, что преимущества парадигмы перевесят недостатки, по крайней мере, для некоторых программистов.

ответил Tyler Durden 21 MarpmTue, 21 Mar 2017 21:30:11 +03002017-03-21T21:30:11+03:0009 2017, 21:30:11
0

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

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

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

ответил 23 MarpmThu, 23 Mar 2017 16:15:40 +03002017-03-23T16:15:40+03:0004 2017, 16:15:40
0

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

Цель - Управлять программной сложностью . Цель не «использовать язык OO».

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


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


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

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

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

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

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

ответил displayName 25 MaramSat, 25 Mar 2017 02:31:39 +03002017-03-25T02:31:39+03:0002 2017, 02:31:39
0

Единственное, что нужно помнить, это следующее:
ООП не относится к языковым функциям; это о том, как вы структурируете свой код .

ООП - это способ мышления и проектирования архитектуры вашего кода, и это можно сделать практически на любом языке. Это особенно относится к тем низкоуровневым, не-OO-языкам, которые называются ассемблером и C. Вы можете отлично выполнять объектно-ориентированное программирование на ассемблере, а ядро ​​Linux, написанное на C, довольно объектно-ориентированное во многих аспектах .

Тем не менее, функции OO на языке значительно уменьшают количество кода шаблона, которое нужно написать для достижения желаемых результатов . Если вам нужно явно определить таблицу виртуальных функций и заполнить ее соответствующими указателями на функции в C, вы просто сделаете nothing в Java, и все готово. Языки OO просто удаляют все, что позволяет использовать треск из исходного кода, скрывая его за красивыми абстракциями на уровне языка (например, классы, методы, члены, базовые классы, неявные вызовы конструктора /деструктора и т. Д.).

Итак, нет, нам не нужны нужны языки OO для OOP. Это просто, что ООП намного проще делать с достойным языком OO.

ответил cmaster 22 MarpmWed, 22 Mar 2017 16:19:34 +03002017-03-22T16:19:34+03:0004 2017, 16:19:34
-1

Объектно-ориентированное программирование - это больше, чем просто модули + инкапсуляция. Как вы говорите, можно использовать модули + инкапсуляцию на не-объектно-ориентированном (процедурный) языке. ООП включает в себя не только это: он включает в себя объекты и методы. Итак, нет, это не захватывает ООП. См. Например, https://en.wikipedia.org/wiki/Object-oriented_programming или введение хорошего учебника в ООП.

ответил D.W. 20 MaramMon, 20 Mar 2017 08:43:49 +03002017-03-20T08:43:49+03:0008 2017, 08:43:49
-2

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

Представим себе систему из 100 классов, каждая из которых имеет около 20 операций, которые могут выполняться на них; это 2 000 функций. Тем не менее, из них, возможно, всего 500 - это полные операции, такие как «Сохранить» и «Удалить», а 1500 - это внутренние функции, которые выполняют немного обслуживания или имеют какую-то служебную роль. Рассмотрим;

//намеренно на неспецифическом языке!

setName (человек, имя) {
    nameParts = splitPersonName (имя);
    person.firstName = nameParts [0];
    person.lastName = nameParts [1];
    person.modified = true;
}

splitPersonName (name) {
    var result = [];
    result.add (name.substring (0, name.indexOf ("")));
    result.add (name.substring (name.indexOf ("") + 1));
    результат возврата;
}

So SetName - это функция, которую люди должны выполнять для человека, но SplitPersonName - это функция утилиты, используемая человек.

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

Вот что public и private do;

public class Person {
    public void setName (...) {...}
    private string [] splitPersonName (...) {...}
}
ответил user62575 20 MarpmMon, 20 Mar 2017 13:31:06 +03002017-03-20T13:31:06+03:0001 2017, 13:31:06

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132