Есть ли у процедурного программирования какие-либо преимущества перед ООП? - PullRequest
36 голосов
/ 09 февраля 2009

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

Однако мой опыт программиста на Java был иным. Я увидел массивную Java-программу, которую я спроектировал, переписал гуру Perl в 1/10 кода, который я написал, и, казалось бы, такой же надежный, как моя модель совершенства ООП. В моей архитектуре было много повторного использования, но более краткий процедурный подход позволил получить превосходное решение.

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

Кто-нибудь может привести примеры того, как эти сценарии будут выглядеть?

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

Ответы [ 22 ]

43 голосов
/ 09 февраля 2009

Мне нравятся Glass ' правила 3, когда дело доходит до повторного использования (что, кажется, то, что вас интересует).

1) Это в 3 раза сложнее создавать повторно используемые компоненты как единое целое использовать компоненты
2) многоразового использования компонент должен быть опробован в три различные приложения, прежде чем это будет быть достаточно общим, чтобы принять в библиотека повторного использования

Исходя из этого, я думаю, вы можете экстраполировать эти следствия

а) Если у вас нет бюджета в 3 раза больше времени для создания одноразового компонента, может быть Вы должны воздерживаться от повторного использования. (При условии сложности = время)
б) если у вас нет 3 мест, где вы бы использовать компонент, который вы строите, может быть, вам стоит остановиться многоразовый компонент.

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

15 голосов
/ 09 февраля 2009

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

14 голосов
/ 09 февраля 2009

Вы сами дали ответ - большие проекты просто нуждаются в ООП, чтобы не запутаться.

С моей точки зрения, самое большое преимущество ООП - это организация кода. Это включает в себя принципы СУХОЙ и инкапсуляции.

12 голосов
/ 10 февраля 2009

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

10 голосов
/ 19 августа 2010

Те, кто религиозно поддерживают ООП, не имеют никаких фактов, оправдывающих их поддержку, как мы видим и в этих комментариях. Их обучают (или промывают мозги) в университетах, чтобы использовать и хвалить только ООП и ООП, и поэтому они так слепо поддерживают это. Они вообще что-то сделали в PP? Кроме защиты кода от неосторожных программистов в командной среде, ООП предлагает мало. Лично работая в PP и OOP в течение многих лет, я считаю, что PP прост, понятен и более эффективен, и я согласен со следующими мудрыми мужчинами и женщинами:

(ссылка: http://en.wikipedia.org/wiki/Object-oriented_programming):

Ряд известных исследователей и программистов критиковали ООП. Вот неполный список:

  • Лука Карделли написал статью под названием « Плохие инженерные свойства объектно-ориентированных языков ».

  • Ричард Столлман писал в 1995 году: «Добавление ООП в Emacs явно не является улучшением; Я использовал ООП при работе с оконными системами Lisp Machine, и я не согласен с обычным мнением, что это превосходный способ программирования ».

  • Исследование Potok et al. не показала существенной разницы в производительности между ООП и процедурным подходом.

  • Кристофер Дж. Дэйт заявил, что критическое сравнение ООП с другими технологиями, в частности реляционными, затруднено из-за отсутствия согласованного и строгого определения ООП. Предлагается теоретическая основа для ООП, которая использует ООП в качестве настраиваемой системы типов для поддержки СУБД.

  • Александр Степанов предположил, что ООП предлагает математически ограниченную точку зрения, и назвал ее «почти таким же обманом, как искусственный интеллект» (возможно, ссылаясь на проекты и маркетинг в области искусственного интеллекта 1980-х годов, которые иногда рассматриваются как чрезмерно усердные). в ретроспективе).

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

  • Джо Армстронг, главный изобретатель Erlang, говорит: «Проблема с объектно-ориентированными языками заключается в том, что у них есть вся эта неявная среда, которую они носят с собой. Вы хотели банан, но получили гориллу с бананом и джунглями ».

  • Ричард Мэнсфилд, автор и бывший редактор COMPUTE! Журнал утверждает, что «как и многие другие интеллектуальные причуда за эти годы (« актуальность », коммунизм,« модернизм »и т. д. история изобилует ими), ООП будет с нами, пока в конечном итоге реальность не утвердится. Но, учитывая, как ООП в настоящее время проникает как в университеты, так и на рабочие места, ООП вполне может оказаться длительным заблуждением. Целые поколения внушаемых программистов продолжают выходить из академии, приверженные ООП и ничего, кроме ООП, на всю оставшуюся жизнь ». Также говорится, что« ООП - это написание программы, а обеспечение безопасности в аэропорту - это полет. ».

6 голосов
/ 09 февраля 2009

Я думаю, что принцип СУХОЙ (не повторяй себя) в сочетании с небольшим проворством - хороший подход. Создайте свою программу постепенно, начиная с самой простой вещи, которая работает, затем добавляйте функции одну за другой и пересматривайте свой код по мере необходимости.

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

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

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

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

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

4 голосов
/ 02 августа 2010

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

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

Вы можете использовать очень эффективные алгоритмы, но они не будут достаточно быстрыми, пока вы не оптимизируете использование кеша. Это может значительно повысить производительность ваших данных в кеше. Это означает, что процессору не нужны выборочные байты из ОЗУ, он знает их. Чтобы достичь этого, вы должны стараться хранить ваши данные близко друг к другу, ваш исполняемый файл и размер данных должны быть минимальными, и стараться использовать как можно меньше указателей (используйте статические глобальные фиксированные массивы, где вы можете себе позволить).

Если вы используете указатели, вы постоянно перепрыгиваете в памяти, и ваш процессор должен каждый раз перезагружать кеш. Код ООП полон указателей: каждый объект хранится по адресу в памяти. Вы вызываете new везде, где ваши объекты распределяются по всей памяти, что делает оптимизацию кеша практически невозможной (если у вас нет распределителя или сборщика мусора, который держит вещи близко друг к другу). Вы вызываете обратные вызовы и виртуальные функции. Компилятор обычно не может встроить виртуальные функции, и вызов виртуальной функции происходит относительно медленно (перейти к VMT, получить адрес виртуальной функции, вызвать ее [это включает в себя передачу параметров и локальных переменных в стек, выполнение функции тогда все выскакивают]). Это очень важно, когда у вас есть цикл от 0 до 1000000 25 раз в секунду. При использовании процедурного стиля нет виртуальных функций, и оптимизатор может встроить все в эти горячие циклы.

4 голосов
/ 09 февраля 2009

Если проект настолько мал, что он будет содержаться в одном классе и не будет использоваться очень долго, я бы подумал об использовании функций. В качестве альтернативы, если используемый вами язык не поддерживает OO (например, c).

3 голосов
/ 09 февраля 2009

Я думаю, что пригодность ООП зависит больше от предметной области, в которой вы работаете, чем от размера проекта. Есть некоторые предметные области (САПР, имитационное моделирование и т. Д.), В которых ООП естественным образом соотносится с соответствующими концепциями. Тем не менее, есть много других доменов, где отображение оказывается неуклюжим и неуместным. Многие люди, использующие ООП для всего, похоже, проводят много времени, пытаясь втиснуть квадратные колышки в круглые отверстия.

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

3 голосов
/ 09 февраля 2009

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

...