ООП против функционального программирования и процедурного

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

Архитектурные примеры оценены!

Ответ 1

Все они хороши по-своему - это просто разные подходы к тем же проблемам.

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

В объектно-ориентированном стиле данные имеют тенденцию нести с собой набор функций.

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

Конечно, сам язык влияет только на тот стиль, который предпочтительнее. Даже на чистом функциональном языке, таком как Haskell, вы можете писать в процедурном стиле (хотя это очень не рекомендуется), и даже на языке процедур, например C, вы можете программировать в объектно-ориентированном стиле (например, в GTK + и EFL API).

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

Выбор, который вы используете, просто имеет смысл для вашего проекта и абстракции, поддерживаемые вашим языком.

Ответ 2

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

Например, если вы делаете видеоигру, в С++ есть более хорошие примеры кода и SDK, так что вам, вероятно, будет лучше с этим. Для небольшого веб-приложения есть несколько отличных фреймворков Python, PHP и Ruby, которые позволят вам быстро и быстро работать. Java - отличный выбор для больших проектов из-за проверки времени компиляции и корпоративных библиотек и платформ.

Случилось так, что стандартные библиотеки для разных языков были довольно маленькими и легко реплицировались - C, С++, Assembler, ML, LISP и т.д. пришли с основами, но, как правило, курили, когда пришли к стандартизации таких вещей, как сетевые коммуникации, шифрование, графика, форматы файлов данных (включая XML), даже основные структуры данных, такие как сбалансированные деревья и хеш-таблицы, были опущены!

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

Ответ 3

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

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

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

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

То же самое для ООП. Язык, подобный Java, не позволяет вам писать процедуры/функции вне класса. Единственный способ передать функцию - обернуть ее в объект, реализующий эту функцию, и затем передать этот объект.

В Python у вас нет этого ограничения.

Ответ 4

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

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

Ответ 5

Чтобы ответить на ваш вопрос, нам нужны два элемента:

  • Понимание характеристик различных стилей/моделей архитектуры.
  • Понимание характеристик различных парадигм программирования.

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

Вкратце и вообще, процедура хороша для модели, которая следует процедуре, OOP хорош для дизайна, а Functional хорош для программирования на высоком уровне.

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

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

Ответ 6

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

Ответ 7

Один из моих друзей пишет графическое приложение, используя NVIDIA CUDA. Приложение прекрасно вписывается в парадигму ООП, и проблема может быть разложена в модули аккуратно. Однако для использования CUDA вам нужно использовать C, который не поддерживает inheritance. Поэтому вам нужно быть умным.

a) Вы разрабатываете умную систему, которая в определенной степени будет эмулировать наследование. Это можно сделать!

i) Вы можете использовать систему hook, которая ожидает, что у каждого дочернего C родителя P будет определенное переопределение для функции F. Вы может заставить детей регистрировать свои переопределения, которые будут храниться и вызываться по мере необходимости.

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

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

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

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