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

32

Я программирую на Java в очень объектно-ориентированном (ОО) стиле. ООП приходит ко мне очень интуитивно, но я очень мало знаю о других видах программирования.

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

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

Авив Кон
источник
9
Поделиться своими исследованиями помогает всем. Расскажите нам, что вы пробовали и почему это не соответствует вашим потребностям. Это свидетельствует о том, что вы потратили время, чтобы попытаться помочь себе, избавляет нас от повторения очевидных ответов и, прежде всего, помогает получить более конкретный и актуальный ответ. Также см. Как спросить
gnat
2
Процедурное программирование - это не то же самое, что функциональное программирование; на самом деле это то же самое, что и объектно-ориентированное программирование, за исключением объектов и классов.
Мейсон Уилер
1
Императивным ООП на самом деле является процедурное программирование, так что это именно то, что вы делаете все время ...
Ingo

Ответы:

68

В Википедии есть хорошие объяснения этим терминам. Несмотря на это, вот резюме:


  • Декларативное программирование является противоположностью императивного программирования - оно определяет, что вычислять, а не как (например, SQL, регулярные выражения).

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

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

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

  • Большинство людей не знают разницы между объектом и абстрактным типом данных
  • Основные языки ООП не упоминают ADT, предоставляют очень слабую поддержку и рекламируют объекты как Единый Истинный Путь.
  • Никто не говорит абстрактное программирование, ориентированное на тип данных (потому что это было бы глупо; вам нужны как ADT, так и объекты).

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

Кроме того, люди обычно бросают вызов взаимозаменяемому императивному / процедурному, иногда противопоставляя его ООП (подразумевая код без абстракций, обычно C), а иногда противопоставляя его функциональному программированию. Насколько я могу судить, термин « структурированное программирование » в основном вышел из употребления (вероятно, потому, что на данный момент большинство людей считают само собой разумеющимся, что goto и globals считаются вредными.)

Doval
источник
3
«запрещает прыжки» довольно универсально; что включает в себя, если / while / etc .. возможно "запрещает произвольные переходы"?
Изката
@Izkata Хороший вопрос, изменился.
Довал
1
Может стоить ссылки на записи в википедии.
Хайлем
И именно поэтому он называется «Ориентированный», а не «Только объект».
JeffO
1
@OrangeDog Чем это отличается от абстрактного типа данных, который также определяет инкапсулированный набор данных и функций, которые могут воздействовать на него? Кроме того, вы можете иметь неизменные объекты, так что в таком случае, в каком состоянии ?
Довал
12

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

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

Бейсик процедурный.

Как уже говорили другие, это механизм последовательного структурирования программ.

  • Сначала я делаю х
  • Во-вторых, я делаю у
  • В-третьих я делаю Z

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

Парадигма не диктует, какими вещами вы будете заниматься, или манерой вещей обойти.

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

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

Один из способов думать об этом с точки зрения объема данных.

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

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

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

Роб Бэйли
источник
5

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

Процедурное программирование - это когда у вас в голове есть модель компьютера как машины, и вы думаете о том, как она модифицирует данные в памяти. Итак, сначала вы устанавливаете Aзначение 3, затем добавляете 1 и Aснова сохраняете его в ячейке памяти (перезаписывая предыдущее значение).

Функциональное программирование будет означать « A3», « Bесть» A + 1, а затем дать компьютеру понять, как рассчитать B. Как только вы определились, Aон должен быть неизменным (неизменяемым). Функциональность также позволяет вам выполнять такие функции, как передача функции в качестве первоклассного значения (функция может принимать функцию в качестве аргумента).

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

Скотт Уитлок
источник
0

ООП - это не более чем утонченная форма процедурного программирования, которая опять-таки принадлежит к большему семейству императивного программирования. Доказательством этого утверждения является то, что многие программисты на C # / Java склонны «что-то делать» и предпочитают такие методы, как:

void doThisAndThat(....) { ... do something ... }

Итак, программа, которая состоит из нескольких void-методов (ранее называвшихся процедурами (sic!)) И такого кода:

doThis();
if (state is that) doSomethingElse();
doThat();

идеальное процедурное программирование.

Инго
источник
doThisAndThat (....) подразумевает, что метод будет делать больше, чем одну вещь, что в целом не является хорошей практикой. Разработчики Java и C # в основном придерживаются принципа единой ответственности. Я думаю, что ваша аналогия ошибочна. objectmentor.com/resources/articles/srp.pdf
JohnK
@JohnK Я знаю, что это не очень хорошая практика. Все же общий. Особенно среди разработчиков Java, если судить по тому, что каждый день видит на SO.
Инго
@JohnK Java и C # разработчики в основном придерживаются принципа единой ответственности - Lip service?
Инго
Разработчики Java в основном придерживаются единой ответственности? Если бы только это было правдой в реальной жизни ...
Шридхар Сарнобат