Вопрос

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

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

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

Это было полезно?

Решение

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

Автомобиль - это транспортное средство, у которого есть ДВИГАТЕЛЬ.Это программирование и реальный мир в одном флаконе!

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

Другие советы

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

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

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

Википедия:

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

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

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

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

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

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

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

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

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

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

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

Верно, это популярно.

" ...доступность инструментов,"

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

"поддержка",

Да, я уверен, что реляционная модель имеет прекрасную поддержку, но она полностью не поддерживается реализацией СУБД.

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

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

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

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

" ...противоречит ООП ".

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

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

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

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

Создание программного обеспечения не имеет ничего общего с фундаментальной физикой.Физики стремятся описать реальность, используя парадигмы, которые могут быть оспорены новыми экспериментальными данными и / или теориями.Физика - это наука, которая ищет "истину" так, как этого не делает разработка программного обеспечения.

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

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

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

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

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

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

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

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

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

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

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

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

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

Немного спорное мнение с моей стороны, но я не нахожу ООП, по крайней мере, такого рода, который широко применяется сейчас, чтобы быть это полезно при создании самого масштабного программного обеспечения в моей конкретной области (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 такой полезной, поскольку она превращает аналогичную физическую систему и все подобные мощные системы в "центральный преобразователь базы данных" или "центральный считыватель базы данных, который выводит что-то новое", которые теперь могут не обращать внимания друг на друга.Затем каждая система начинает больше походить на процесс в плоском конвейере, чем на объект, который образует узел в очень сложном графе связи.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top