ООП против функционального программирования против процедурного [закрыто]
каковы различия между этими парадигмами программирования, и они лучше подходят для конкретных проблем или какие-либо варианты использования предпочитают один над другими?
архитектура примеры приветствуются!
7 ответов:
все они хороши по-своему-это просто разные подходы к одним и тем же проблемам.
в чисто процедурном стиле данные, как правило, сильно отделены от функций, которые работают на нем.
в объектно-ориентированном стиле данные имеют тенденцию нести с собой набор функций.
в функциональном стиле данные и функции имеют тенденцию иметь больше общего друг с другом (как в Lisp и Scheme), предлагая при этом большую гибкость в термины того, как фактически используются функции. Алгоритмы, как правило, также определяются в терминах рекурсии и композиции, а не циклов и итераций.
конечно, сам язык влияет только на то, какой стиль является предпочтительным. Даже на чисто функциональном языке, таком как Haskell, вы можете писать в процедурном стиле (хотя это очень не рекомендуется), и даже на процедурном языке, таком как C, вы можете программировать в объектно-ориентированном стиле (например, в GTK+ и EFL Апис.)
чтобы быть ясным," преимущество " каждой парадигмы заключается просто в моделировании ваших алгоритмов и структур данных. Если, например, ваш алгоритм включает в себя списки и деревья, функциональный алгоритм может быть наиболее разумным. Или, если, например, ваши данные сильно структурированы, может иметь больше смысла составлять их как объекты, если это родная парадигма вашего языка - или она может быть так же легко написана как функциональная абстракция монад, которая является родной парадигма языков, таких как Haskell или ML.
выбор, который вы используете, - это просто то, что имеет больше смысла для вашего проекта и абстракций, которые поддерживает ваш язык.
Я думаю, что доступные библиотеки, инструменты, примеры и сообщества полностью превосходят парадигму в эти дни. Например, ML (или что-то еще) может быть конечным универсальным программированием язык но если вы не можете получить хорошие библиотеки для того, что вы делаете, вы облажались.
например, если вы делаете видеоигру, есть более хорошие примеры кода и SDK в C++, так что вам, вероятно, лучше с этим. Для небольшого веб-приложения, есть некоторые отличные Python, PHP и Ruby фреймворки, которые помогут вам быстро и быстро работать. Java-отличный выбор для больших проектов из-за проверки времени компиляции и корпоративных библиотек и платформ.
раньше было так, что стандартные библиотеки для разных языков были довольно маленькими и легко реплицировались - C, C++, ассемблер, ML, LISP и т. д.. пришел с основами, но, как правило, курица, когда дело доходит до стандартизации на таких вещах, как сетевые коммуникации, шифрование, графика, форматы файлов данных (включая XML), даже основные структуры данных, такие как сбалансированные деревья и хэш-таблицы, были опущены!
современные языки, такие как Python, PHP, Ruby и Java теперь поставляются с гораздо более приличной стандартной библиотекой и имеют много хороших сторонних библиотек, которые вы можете легко использовать, во многом благодаря их принятию пространств имен, чтобы библиотеки не сталкивались друг с другом, и сбор мусора для стандартизации схем управления памятью библиотеки.
эти парадигмы не должны быть взаимоисключающими. Если вы посмотрите на python, он поддерживает функции и классы, но в то же время все является объектом, включая функции. Вы можете смешивать и сочетать функциональный/ООП / процедурный стиль в одном фрагменте кода.
Я имею в виду, что в функциональных языках (по крайней мере, в Haskell, единственном, который я изучал) нет утверждений! функции имеют только одно выражение внутри них!! Но, функции-это первоклассные граждане, вы может передавать их как параметры, наряду с кучей других способностей. Они могут делать мощные вещи с несколькими строками кода.
в то время как на процедурном языке, таком как C, единственный способ передать функции-это использовать указатели функций, и это само по себе не позволяет выполнять много мощных задач.
в python функция является первоклассным гражданином, но она может содержать произвольное количество операторов. Таким образом, вы можете иметь функцию, которая содержит процедурный код, но вы можете передать это вокруг так же, как функциональные языки.
то же самое касается ООП. Язык, как Java не позволяет писать процедуры/функции вне класса. Единственный способ передать функцию - это обернуть ее в объект, который реализует эту функцию, а затем передать этот объект.
в Python у вас нет этого ограничения.
для GUI я бы сказал, что объектно-ориентированная парадигма очень хорошо подходит. Окно-это объект, текстовые поля-это объекты, и кнопка OK-тоже одна. С другой стороны такие вещи, как обработка строк можно сделать с гораздо меньшими издержками, поэтому проще процедурная парадигма.
Я не думаю, что это вопрос языка ни. Вы можете написать функциональный, процедурный или объектно-ориентированный практически на любом популярном языке, хотя это может быть некоторые дополнительные усилия в некоторых.
чтобы ответить на ваш вопрос, нам нужны два элемента:
- понимание особенностей различных архитектурных стилей/шаблонов.
- понимание особенностей различных парадигм программирования.
список стилей/шаблонов архитектуры программного обеспечения отображается на программная архитектура статьи на Wikipeida. И вы можете легко исследовать их в интернете.
короче и в целом, Процедурный хорош для модели, которая следует за процедурой, ООП хорош для дизайна, а функциональный хорош для программирования высокого уровня.
Я думаю, что вы должны попробовать прочитать историю на каждой парадигме и посмотреть, почему люди создают его, и вы можете легко понять их.
после понимания их обоих, вы можете связать элементы архитектурных стилей/шаблонов, парадигм программирования.
Я думаю, что они часто не "против", но вы можете комбинировать их. Я также думаю, что часто слова, которые вы упоминаете, являются просто модными словами. Мало кто действительно знает, что такое" объектно-ориентированный", даже если они самые яростные его проповедники.
один из моих друзей пишет графическое приложение с помощью NVIDIA CUDA. Приложение очень хорошо вписывается в парадигму ООП, и проблема может быть аккуратно разложена на модули. Однако для использования CUDA вам нужно использовать C, который не поддерживает наследование. Поэтому нужно быть умным.
а) вам разработать умную систему, которая будет эмулировать наследование в определенной степени. Это можно сделать!
i) вы можете использовать система крюк, который ожидает, что каждый дочерний элемент C родительского P будет иметь определенное переопределение для функции F. Вы можете заставить детей регистрировать свои переопределения, которые будут сохранены и вызваны при необходимости.
ii) вы можете использовать struct выравнивание памяти функция, чтобы бросить детей на родителей.
Это может быть аккуратно, но это не так легко придумать будущее доказательство, надежное решение. Вы будете тратить много времени на разработку системы и нет никакой гарантии, что вы не столкнетесь проблемы на полпути через проект. Реализация множественное наследование еще сложнее, если не почти невозможно.
b) вы можете использовать согласованную политику именования и использовать разделяй и властвуй подход к созданию программы. Он не будет иметь никакого наследования, но поскольку ваши функции малы, просты для понимания и последовательно отформатированы, вам это не нужно. Количество кода, которое вам нужно написать, растет, очень трудно оставаться сосредоточенным и не поддаваться легко решениях (хаки). Однако этот способ кодирования ниндзя - это способ кодирования C. Оставаясь в балансе между низкоуровневой свободой и написанием хорошего кода. Хороший способ добиться этого-написать прототипы с использованием функционального языка. Например, Haskell - это очень хорошо для прототипирования.
Я склоняюсь к подходу б. Я написал возможное решение, используя подход, и я буду честен, он чувствовал себя очень неестественно, используя этот код.