Значительные претенденты на ООП - PullRequest
15 голосов
/ 03 июня 2009

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

Существуют ли сценарии, когда действительно не ООП-парадигма на самом деле является лучшим выбором для крупномасштабного решения? Или это неслыханно в наши дни?

Я удивлялся этому с тех пор, как начал изучать CS; легко почувствовать, что ООП - это некая нирвана программирования, которая никогда не превзойдет.

Ответы [ 12 ]

10 голосов
/ 03 июня 2009

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

АВТОМОБИЛЬ - АВТОМОБИЛЬ, ДВИГАТЕЛЬ. Это программирование и реальный мир все в одном!

Трудно понять все, что может вписаться в программирование и реальный мир, настолько элегантно.

7 голосов
/ 03 июня 2009

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

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

4 голосов
/ 08 апреля 2010

Вы могли бы взглянуть на Эрланга, написанный Джо Армстронгом.

Википедия:

"Эрланг универсальный язык параллельного программирования и система времени выполнения. Последовательное подмножество Эрланг это функциональный язык, со строгой оценкой, холост назначение и динамическая типизация. "

Джо Армстронг:

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

3 голосов
/ 03 июня 2009

Обещанием ООП было повторное использование кода и более простое обслуживание. Я не уверен, что это доставлено. Я считаю, что такие вещи, как dot net, очень похожи на библиотеки C, которые мы использовали для различных поставщиков. Вы можете назвать этот код повторно, если хотите. Что касается обслуживания плохой код плохой код. ООП не помогло.

2 голосов
/ 03 июня 2009

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

2 голосов
/ 03 июня 2009

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

Хотя я понимаю, что виртуализация ООП может вызвать проблемы с производительностью. Конечно, это зависит от вашего дизайна, языка и платформы, которую вы выбрали (системы, написанные на языках на основе сборки мусора, таких как Java или C #, могут работать хуже, чем системы, которые были написаны, например, на C ++).

Полагаю, в системах реального времени процедурное программирование может быть более подходящим.

1 голос
/ 26 мая 2010

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

То, что мы начинаем видеть, - это мультипарадигмальные подходы с декларативными и функциональными идеями, включенными в объектно-ориентированные проекты. Большинство новых языков JVM являются хорошим примером этого (JavaFX, Scala, Clojure и т. Д.), А также LINQ и F # на платформе .net.

Важно отметить, что я здесь говорю не о замене ОО, а о ее дополнении.

  • JavaFX показал, что декларативный решение выходит за рамки SQL и XSLT, и также может быть использован для привязки свойства и события между визуальным компоненты в графическом интерфейсе

  • Для отказоустойчивых и высоко параллельные системы, функциональные программирование очень хорошо подходит, как продемонстрировал Эрикссон AXD301 (программируется с использованием Erlang)

Итак ... поскольку параллелизм становится все более важным и FP становится все более популярным, я думаю, что пострадают языки, не поддерживающие эту парадигму. Это включает в себя многие популярные в настоящее время, такие как C ++, Java и Ruby, хотя JavaScript должен справляться очень хорошо.

1 голос
/ 04 июня 2009

См. это и это . Очевидно, вы можете использовать C # с пятью разными парадигмами программирования, C ++ с тремя и т. Д.

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

Разработка программного обеспечения - это бизнес . Вы должны быть продуктивным , т.е. для достижения некоторых целей, за которые кто-то будет платить деньги. Парадигмы используются потому, что они полезны для эффективного производства программного обеспечения . Вам не нужно, чтобы все соглашались. Если я делаю ООП, и он работает хорошо для меня, мне все равно, будет ли «новая» парадигма потенциально полезной для меня на 20%, если у меня будет время и деньги, чтобы изучить ее, а затем переосмыслить всю структуру программного обеспечения, которую я Я работаю над этим и перепроектирую его с нуля.

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

1 голос
/ 04 июня 2009

Zyx, вы писали: «Большинство систем используют реляционные базы данных ...»

Боюсь, такого нет. В следующем году реляционной модели исполнится 40 лет, и она так и не была реализована. Я думаю, что вы имеете в виду «базы данных SQL». Вы должны прочитать что-нибудь от Фабиана Паскаля, чтобы понять разницу между реляционными БД и БД SQL.

"... реляционная модель обычно выбирается из-за ее популярности"

Правда, это популярно.

"... наличие инструментов"

Увы, без основного необходимого инструмента: реализация реляционной модели.

«поддержка»

Да, у реляционной модели есть хорошая поддержка, я уверен, но она полностью не поддерживается реализацией dbms.

"и тот факт, что реляционная модель на самом деле является математическим понятием"

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

На самом деле, несмотря на то, что это математическая концепция, это, конечно, не наука (как в компьютерных науках), потому что в ней отсутствует первое требование любой науки: ее фальсификация: нет реализации реляционных БД, против которых мы можете проверить свои претензии.

Это чистое змеиное масло.

"... вопреки ООП."

И вопреки ООП, реляционная модель никогда не была реализована.

Купите книгу по SQL и станьте продуктивным.

Оставьте реляционную модель непродуктивным теоретикам.

0 голосов
/ 07 февраля 2018

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

Трудность, с которой я часто сталкиваюсь, заключается в том, что, если у вас есть все эти маленькие конкретные объекты, инкапсулирующие данные, они теперь хотят общаться друг с другом. Взаимодействия между ними могут быть чрезвычайно сложными, например (кроме гораздо более сложного в реальном приложении, охватывающем тысячи объектов):

enter image description here

И это не граф зависимостей, непосредственно связанный со связью, а "граф взаимодействия". Могут быть абстракции, чтобы отделить эти конкретные объекты друг от друга. Foo может не общаться с Bar напрямую. Вместо этого он может говорить с ним через IBar или что-то в этом роде. Этот график по-прежнему соединяет Foo с Bar, поскольку, хотя они и отделены, они все еще общаются друг с другом.

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

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

enter image description here

... или это:

enter image description here

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

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

"Программирование на конвейере" с минимальными знаниями

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

Тестирование по-прежнему довольно простое из-за узкой направленности каждой подсистемы. Мы больше не копируем конкретные объекты с помощью внедрения зависимостей, а просто генерируем минимальный объем данных, относящихся к конкретной системе, и проверяем, обеспечивает ли конкретная система правильный вывод для данного ввода. С таким небольшим количеством тестируемых систем (только десятки могут составить сложное программное обеспечение), это также значительно сокращает количество необходимых тестов.

Разрыв инкапсуляции

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

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

Глобальные данные

Я должен признать, что сначала очень не решался применить ECS к архитектурному дизайну в моей области, поскольку, во-первых, этого не было раньше, насколько я знал популярных коммерческих конкурентов (3DS Max, SoftImage и т. Д.) и, во-вторых, это выглядит как целая куча глобально доступных данных.

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

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

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

Гибкость и расширяемость

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

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

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

Превращение объектов в данные

В предыдущей ООП-тяжелой кодовой базе, где я видел трудности с поддержанием кодовой базы ближе к первому графику, приведенному выше, количество требуемого кода взорвалось, потому что аналог Car на этой диаграмме:

enter image description here

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

Когда я сравнил его с ECS, для этого потребовались только сотни, и мы смогли сделать то же самое, прежде чем использовать небольшую часть кода, потому что это превратило аналогичный объект Car в нечто, что больше не требует его класса , Он превращается в простой набор компонентных данных как обобщенный экземпляр только одного Entity типа.

Альтернативы ООП

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

Сравнивая две системы, над которыми я работал в прошлом и сейчас, новая имеет больше возможностей, но занимает сотни тысяч LOC. Первому требовалось более 20 миллионов LOC. Конечно, это не самое справедливое сравнение, так как у предыдущей было огромное наследие, но если вы возьмете часть двух систем, которые функционально вполне равны без унаследованного багажа (по крайней мере, примерно так же близко, как мы могли бы получить), ECS использует небольшую часть кода, чтобы сделать то же самое, и отчасти потому, что он значительно сокращает число классов в системе, превращая их в коллекции (сущности) необработанных данных (компонентов) с помощью здоровенных систем для их обработки. из лодки малых / средних объектов.

Существуют ли сценарии, когда действительно не ООП-парадигма на самом деле лучший выбор для крупномасштабного решения? Или это неслыханно дней

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

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

Кодирование высокого уровня

Но мне кажется, что обычно это решения более высокого уровня почти всегда собраны в ООП моды.

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

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

Интернет общения

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

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

...