Поддерживают ли не-ООП парадигмы такие понятия, как инкапсуляция?

12

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

Это заставляет меня задуматься, а как насчет инкапсуляции и других принципов ООП? Они не правы?

ООП применяется неправильно? Например, Алан Кей известен тем, что сказал в OOPSLA'97 Keynote: «Я изобрел термин объектно-ориентированный, и я могу сказать, что я не имел в виду C ++».

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

JeffV
источник
2
Я бы сказал, что сначала вопрос должен прояснить, что подразумевается под инкапсуляцией и что означает язык для ее поддержки.
Эйфорическая
14
У меня проблемы с выяснением того, что задает этот вопрос. Спрашивается, может ли инкапсуляция существовать вне OO (строка темы)? Это спрашивает, является ли инкапсуляция неправильной (второй абзац)? Спрашивает, применяется ли ОО неправильно (третий абзац)? И что ОП хочет сказать этой цитатой Джо Армстронга? Как ОП определяет «инкапсуляцию»? Как ОП определяет «ОО»? Что это за "другие принципы"?
Йорг Миттаг
1
Роберт Мартин однажды сказал, что ООП убрал инкапсуляцию, а затем исправил ее с помощью ужасных хаков. «У нас была идеальная инкапсуляция до oO». Конечно, он был гиперболичен, но теперь каждый раз, когда я вижу, что кто-то говорит, что ОО - это инкапсуляция, я помню дядю Боба.
GnP

Ответы:

15

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

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

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

ООП применяется неправильно?

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

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


источник
10

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

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

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

Это заставляет меня задуматься, а как насчет инкапсуляции и других принципов ООП? Они не правы?

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

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

ООП применяется неправильно? Например, Алан Кей известен тем, что сказал в OOPSLA'97 Keynote: «Я изобрел термин объектно-ориентированный, и я могу сказать, что я не имел в виду C ++».

Конечно, ООП часто применяется неправильно многими людьми, но я уверен, что то же самое верно и для ФП. И я был бы удивлен, если бы Джон МакКарти (дизайнер Lisp) имел в виду что-то вроде Javascript, когда думал о функциональном программировании (пощадите меня, не расстраивайте меня слишком сильно для такого сравнения ;-)

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

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

Док Браун
источник
1
Я не уверен, что OO особенно лучше для GUI, тем более что OO и GUI появились примерно в одно и то же время. +1 для Маккарти / Javascript хотя;)
JK.
1
Чтобы быть справедливым, некоторые люди предполагают, что существующие подходы несовершенны и могут быть заменены чем-то другим . Я не знаю, назову ли я это «расширением» или, скорее, «улучшением» набора инструментов :)
Andres F.
1
@AndresF. Это фантастическое чтение. Я планирую подробно ознакомиться с этим документом, когда у меня будет время.
Роберт Харви
4

Конечно:

struct Foo
{
    string bar;
    int bux;
}

Я знаю, что вы скажете: «Но это также не отражает поведение!» Я согласен с Джо Армстронгом: вы можете писать целые программы или операционные системы, не требуя первоклассных объектов. Linux доказывает это.

Программисты Javascript обычно инкапсулируют состояние и поведение в функции и замыкания, а не в классы.

Роберт Харви
источник
3
Вы также можете засыпать холм грязью только чайной ложкой. Но к любому, кто заявляет, что это оптимальный способ, следует относиться с подозрением.
Эйфорическая
6
Я никогда не говорил, что это оптимально, и это не то, о чем спрашивает ОП. В других новостях я нахожу забавным, что Linux квалифицируется как перелопачивание грязи чайной ложкой.
Роберт Харви
2
@jk. Конечно. Как и С, своего рода.
Роберт Харви
1
на самом деле это вроде как
JK.
4
Я бы не назвал структуры C «инкапсуляцией». Они не защищают данные и не предоставляют никаких стандартизированных методов доступа к ним. Они просто избавят вас от ручной арифметики указателей. Например, довольно часто можно найти сетевой код, который преобразует сериализованные пакеты в структуры и наоборот. Получите неправильный порядок байтов в сети и получите удовольствие.
david25272
2

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

Первое определение, которое вы найдете, это

Инкапсуляция - это концепция, которая связывает воедино данные и функции, которые манипулируют данными ...

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

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

... и это защищает как от постороннего вмешательства, так и от неправильного использования.

Википедия также соглашается с этим:

Языковой механизм для ограничения прямого доступа к некоторым компонентам объекта.

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

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

Но как насчет неизменных языков? Это не проблема мутирующих переменных. Вот тут и возникает вторая проблема: связывание функций и данных позволяет поддерживать эти данные в состоянии, которое является действительным. Представьте, что у вас есть неизменяемая структура Email. Эта структура имеет одно stringполе. У нас есть требования, что если у вас есть значение типа, Emailто это поле содержит действительный адрес. В инкапсуляции ООП это легко сделать, объявив это поле private, предоставив только Getметод иconstructor methodэто только успешно, если передано в строке является действительным адресом. Аналогичная вещь с замыканиями. Теперь для неизменяемого языка нужно сказать, что структура может быть инициализирована только через определенную функцию, и такая функция может потерпеть неудачу. И я не знаю ни одного языка, который бы соответствовал этим критериям (возможно, кто-то в комментариях может просветить меня).

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

Euphoric
источник