Одним из важных понятий в объектно-ориентированном программировании является инкапсуляция. Однако в последнее время мир программного обеспечения склоняется в пользу других парадигм, таких как функциональное программирование.
Это заставляет меня задуматься, а как насчет инкапсуляции и других принципов ООП? Они не правы?
ООП применяется неправильно? Например, Алан Кей известен тем, что сказал в OOPSLA'97 Keynote: «Я изобрел термин объектно-ориентированный, и я могу сказать, что я не имел в виду C ++».
Джо Армстронг - «Объекты связывают функции и структуры данных вместе в неделимых единицах. Я думаю, что это фундаментальная ошибка, поскольку функции и структуры данных принадлежат совершенно разным мирам».
Ответы:
Я думаю, что ловушка, в которую вы попали, заключается в том, что существует жесткое определение любой парадигмы программирования (структурированной, объектно-ориентированной, функциональной и т. Д.).
Если вы спросите двух разных разработчиков, что означает ООП, вы получите два разных ответа. Да, как профессия, мы согласны с тем, что есть несколько общих тем, таких как инкапсуляция, сокрытие данных и т. Д., Охватываемых любым классом разработки программного обеспечения ООП в колледже.
Тем не менее , в реальном мире все не так просто, поэтому два разработчика дадут два разных ответа. Возможно, они являются экспертами в разных языках, которые по-разному выражают концепции ООП. Языковые парадигмы имеют тенденцию пересекаться. Последняя ярость, появившаяся примерно в 2013 году, включает функциональное программирование на объектно-ориентированных языках через замыкания или лямбды. Является ли Java 8 объектно-ориентированным или функциональным? Я бы назвал это объектно-ориентированным с чертой функционала. Кто-то еще может описать это по-другому.
Нет, проблема в том, что разные языки по-разному выражают концепции программирования. Возможно, один язык исключает концепцию ООП, а другой язык включает ее, но исключает другую концепцию ООП. Языки, как правило, предназначены для определенной цели: упростить задачу определенного типа за счет усложнения других задач. Это ни правильно, ни неправильно, это просто реальный компромисс, которого невозможно избежать.
Реальный мир - это не классная комната. Нам либо нужно обсудить концептуальные парадигмы программирования на абстрактном уровне, либо нам нужно обсудить реальные языки программирования, которые вынуждены делать компромиссы, чтобы быть полезными. Поскольку язык программирования в основном определяется абстрактным определением ООП, мы можем включить его в этот сегмент.
источник
Это спорно. Во-первых, я не вижу никаких других парадигм, кроме ООП и функционального программирования, которые широко обсуждаются, поэтому я думаю, что мы можем забыть фразу «как другие парадигмы» , давайте поговорим о FP, и ничего больше.
Причины, по которым функциональное программирование стало настолько популярным в последние годы, подробно обсуждались здесь в других вопросах, я не буду повторять это (см. Здесь или здесь , например). Но, на мой взгляд, это не потому, что «ООП была большой ошибкой» или «Функциональные и ООП взаимоисключающие», это больше похоже на то, как люди расширяют свой инструментарий и пытаются получить лучшее из обоих миров. Хорошо, конечно, есть эксперты, которые являются сторонниками жесткой линии, предпочитающими одного над другим, но вы найдете этих парней с обеих сторон.
Инкапсуляция имеет много разных вкусов. Языки функционального программирования и языковые конструкции обеспечивают определенные формы инкапсуляции, объектно-ориентированные другие. Если вы ищете примеры инкапсуляции с функциональными средствами, начните с замыканий .
Относительно «других принципов»: нет, они не ошибаются, но для определенных сценариев, таких как распараллеливание больших масштабов, функциональные подходы, вероятно, масштабируются лучше. Для других сценариев, таких как создание хорошо спроектированных структур пользовательского интерфейса, подходы ООП масштабируются, вероятно, лучше (YMMV, у меня не просто есть лучший пример под рукой). Более того, я уверен, что для большинства сценариев реального мира это зависит от знаний и опыта команды с ее любимой парадигмой программирования, насколько хорошо масштабируется определенная система.
Конечно, ООП часто применяется неправильно многими людьми, но я уверен, что то же самое верно и для ФП. И я был бы удивлен, если бы Джон МакКарти (дизайнер Lisp) имел в виду что-то вроде Javascript, когда думал о функциональном программировании (пощадите меня, не расстраивайте меня слишком сильно для такого сравнения ;-)
Я полагаю, что у изобретателя Эрланга есть несколько веских аргументов, но у него есть и своя собственная точка зрения, поэтому дайте ему свое мнение и постройте свое собственное. Есть много других экспертов, которые имеют другое представление об этом.
источник
Конечно:
Я знаю, что вы скажете: «Но это также не отражает поведение!» Я согласен с Джо Армстронгом: вы можете писать целые программы или операционные системы, не требуя первоклассных объектов. Linux доказывает это.
Программисты Javascript обычно инкапсулируют состояние и поведение в функции и замыкания, а не в классы.
источник
Основная проблема здесь заключается в том, что инкапсуляция не является жестко определенным понятием, и почему это не полезно. Проведение некоторых исследований показывает, что то, как люди видят инкапсуляцию, очень самоуверенно, и что многие люди путают ее с абстракцией.
Первое определение, которое вы найдете, это
Если это ваше определение, то большинство языков имеют возможность группировать данные и функции, работающие с этими данными, в классы, модули, библиотеки, пространства имен и т. Д.
Но я бы сказал, что это не главная цель инкапсуляции, поскольку это определение продолжается:
Википедия также соглашается с этим:
Но теперь нам нужно спросить, что подразумевается под «вмешательством и неправильным использованием» и почему должен быть ограничен прямой доступ к данным. Я считаю, что есть две причины.
Во-первых, это ограничивающая область, в которой данные могут быть изменены, в интересах разработчика. Слишком часто возникает необходимость в логике до / после установки значения. И иметь ограниченное количество мест, где можно установить значение, чрезвычайно ценно. На языках ООП это можно сделать с помощью классов. В «изменчивых» функциональных языках замыкания служат той же цели. И потому , что мы знаем классы = замыкания , это даже спорно , чем изменяемые функциональные языки отличаются «парадигма» ООП.
Но как насчет неизменных языков? Это не проблема мутирующих переменных. Вот тут и возникает вторая проблема: связывание функций и данных позволяет поддерживать эти данные в состоянии, которое является действительным. Представьте, что у вас есть неизменяемая структура
Email
. Эта структура имеет одноstring
поле. У нас есть требования, что если у вас есть значение типа,Email
то это поле содержит действительный адрес. В инкапсуляции ООП это легко сделать, объявив это полеprivate
, предоставив толькоGet
метод иconstructor method
это только успешно, если передано в строке является действительным адресом. Аналогичная вещь с замыканиями. Теперь для неизменяемого языка нужно сказать, что структура может быть инициализирована только через определенную функцию, и такая функция может потерпеть неудачу. И я не знаю ни одного языка, который бы соответствовал этим критериям (возможно, кто-то в комментариях может просветить меня).Последняя проблема заключается в том, что подразумевается под языком «поддерживающей» инкапсуляции. С одной стороны, есть языки, которые позволяют применять инкапсуляцию, чтобы код не компилировался, если инкапсуляция нарушена. С другой стороны, язык может обеспечить способ инкапсуляции, но он не обеспечивает его выполнение, оставляя разработчику возможность применять его самостоятельно. Во втором случае может работать любой язык, имеющий структуры и функции. Динамические языки и Haskell приходят на ум. И я бы сказал, что на другой стороне спектра не так много языков. Даже C #, который действительно хорош в обеспечении инкапсуляции для своих объектов, можно обойти с помощью отражения. Но, увидев это в C #, можно было бы считать массивным запахом кода, и ни один здравомыслящий C # разработчик не сделал бы этого охотно.
источник