Ориентируется ли объект архитектуры Entity Component System по определению?

20

Является ли архитектура Entity System Component ориентированный объект, по определению? Это кажется более процедурным или функциональным для меня. Мое мнение таково, что это не мешает вам реализовать его на языке ОО, но это не будет идиоматичным, если вы будете делать это абсолютно уверенно.

Кажется, что ECS отделяет данные (E & C) от поведения (S). В качестве доказательства :

Идея в том, чтобы в сущности не было встроенных игровых методов.

И :

Компонент состоит из минимального набора данных, необходимых для конкретной цели

Системы представляют собой одноцелевые функции, которые принимают набор объектов, имеющих определенный компонент


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

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

ECS, с другой стороны, похоже, все об отделении ваших данных от вашего поведения.

Даниэль Каплан
источник

Ответы:

21

Вступление


Сущностно-компонентные системы являются объектно-ориентированной архитектурной техникой.

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

Это объектная модель, отличная от «классов и наследования», к которой вы, скорее всего, привыкли работать в C ++ или Java. Сущности так же выразительны, как классы, так же, как прототипы, как в JavaScript или Self - все эти системы могут быть реализованы в терминах друг друга.

 

Примеры


Давайте скажем , что Playerявляется юридическим лицом с Position, Velocityи KeyboardControlledкомпонентов, которые делают очевидные вещи.

entity Player:
  Position
  Velocity
  KeyboardControlled

Мы знаем , что Positionдолжны быть затронуты Velocity, и Velocityпо KeyboardControlled. Вопрос в том, как мы хотели бы смоделировать эти эффекты.

 

Сущности, компоненты и системы


Предположим, что компоненты не имеют ссылок друг на друга; внешняя Physicsсистема пересекает все Velocityкомпоненты и обновляет Positionсоответствующую сущность; Inputсистема проходит через все KeyboardControlledкомпоненты и обновляет Velocity.

          Player
         +--------------------+
         | Position           | \
         |                    |  Physics
       / | Velocity           | /
  Input  |                    |
       \ | KeyboardControlled |
         +--------------------+

Это удовлетворяет критериям:

  • Сущность не выражает игровую / бизнес-логику.

  • Компоненты хранят данные, описывающие поведение.

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

 

Сущности и компоненты


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

class Player:
  construct():
    this.p = Position()
    this.v = Velocity(this.p)
    this.c = KeyboardControlled(this.v)

Теперь объект может отправлять события ввода и обновлять данные напрямую своим компонентам. Velocityбудет отвечать на обновления и KeyboardControlledбудет реагировать на ввод. Это все еще удовлетворяет нашим критериям:

  • Сущность является «тупым» контейнером, который только перенаправляет события компонентам.

  • Каждый компонент определяет свое собственное поведение.

Здесь взаимодействие компонентов является явным, а не навязывается системой извне. Данные, описывающие поведение (какова величина скорости?) И код, который его определяет (какова скорость?), Связаны, но естественным образом. Данные можно рассматривать как параметры поведения. А некоторые компоненты не действуют вообще Position- это поведение на месте .

Взаимодействия могут обрабатываться на уровне объекта («когда Playerстолкновение с Enemy…») или на уровне отдельных компонентов («когда объект с Lifeсталкивается с объектом с Strength…»).

 

Компоненты


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

function Player():
  t = Tag("Player")
  p = Position()
  v = Velocity(p)
  c = KeyboardControlled(v)
  return {t, p, v, c}
  • Сущности настолько глупы, насколько это возможно - они просто наборы компонентов.

  • Компоненты отвечают непосредственно на события, как и раньше.

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

 

Вывод


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

Джон Перди
источник
2
Похоже, что основная альтернатива ОО на основе классов - ОО на основе прототипов - связывает данные и поведение. На самом деле, похоже, что он отличается от ECS так же, как OO на основе классов. Так могли бы вы уточнить, что вы подразумеваете под ОО?
Чтобы добавить к вопросу @ delnan, вы не согласны с фрагментом статьи о Википедии OO, которую я цитировал?
Даниэль Каплан
@tieTYT: цитата из Википедии говорит о инкапсуляции и сокрытии информации. Я не думаю, что это доказательство того, что связь между данными и поведением необходима, только то, что она распространена.
Джон Перди
@delnan: Я ничего не имею в виду под ОО. Мне кажется, что объектно-ориентированное программирование - это именно то, что говорится в «банке»: программирование с «объектами» (в отличие от функций, правил, действующих лиц, комбинаторов потоков данных и т. Д.), Где конкретное определение объекта определяется реализацией.
Джон Перди
1
@tieTYT: Я просто описывал реализации, которые я видел в дикой природе, чтобы передать, что это широкий термин - не противоречащий, но, безусловно, более широкий, чем описание в Википедии.
Джон Перди
20

NO. И я удивлен, как много людей проголосовало за иное!

парадигма

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


Функциональная?

Ваше сравнение с функциональным / процедурным программированием является уместным и значимым сравнением. Однако обратите внимание, что «функциональный» язык отличается от «процедурной» парадигмы . И вы можете внедрить ECS на функциональном языке, таком как Haskell , что и сделали люди.


Где сплоченность происходит

Ваше наблюдение является актуальной и спот- :

«... [ECS] не мешает вам реализовать его на языке OO, но это не было бы идиоматично, если бы вы делали это строго OO»


ECS / ES не является EC / CE

Существует разница между компонентно-ориентированными архитектурами, «Entity-Component» и «Entity-Component-System». Поскольку это развивающийся шаблон проектирования, я видел, что эти определения используются взаимозаменяемо. Архитектуры «EC», «CE» или «Entity-Component» определяют поведение компонентов , в то время как архитектуры «ES» или «ECS» определяют поведение систем . Вот некоторые статьи ECS, обе из которых используют вводящую в заблуждение номенклатуру, но дают общее представление:

Если вы пытаетесь понять эти термины в 2015 году, убедитесь, что чья-то ссылка на «Систему компонентов сущностей» не означает «Архитектура компонентов сущностей».

щенок
источник
1
Это правильный ответ. ECS не очень хорошо подходит для парадигм ООП, потому что ECS - это разделение данных и поведения, а ООП - наоборот.
Nax 'vi-vim-nvim'
«в то время как ООП противоположен» Не существует общепринятого определения того, что такое ООП, за исключением бесполезных научных определений, таких как SmallTalk, которые никогда не используются на практике.
Жан-Мишель Селерье
10

Системы компонентов объектов (ECS) могут быть запрограммированы ООП или функциональным образом в зависимости от того, как определена система.

ООП способ:

Я работал над играми, где сущность была объектом, состоящим из различных компонентов. У сущности есть функция обновления, которая изменяет объект на месте, вызывая update для всех его компонентов по очереди. Это явно ООП в стиле - поведение связано с данными, и данные являются изменчивыми. Сущности - это объекты с конструкторами / деструкторами / обновлениями.

Более функциональный способ:

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

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

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

АГД
источник
Больше тяги, особенно потому, что весь смысл компонентов был в том, чтобы уйти от неразрешимых иерархий ООП, что является хорошим описанием преимущества.
Патрик Хьюз
2

Компонентные системы объектов, ориентированные на данные, могут сосуществовать с объектно-ориентированными парадигмами: - Системы компонентов поддаются полиморфизму. - Компоненты могут быть как POD (обычные старые данные), так и объектами ALSO (с классом и методами), и все это по-прежнему «ориентировано на данные», при условии, что методы класса компонентов обрабатывают только данные, принадлежащие локальному объекту.

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

Примером может служить vec2 или vec3, контейнер данных с некоторыми методами для обработки этих данных, и ничего более.

Homer
источник
2
этот пост довольно трудно читать (стена текста). Не могли бы вы изменить его в лучшую форму? Кроме того , было бы полезно , если бы вы объяснить читателям , почему они могут найти ссылки на блог статью полезной и отношение к вопросу спросил ...
комар
... в случае, если вы как-то связаны с этим блогом (не так ли?), было бы также желательно раскрыть информацию о членстве
комнат
Да, это мой блог, я тесно связан с моим общедоступным блогом, в котором раскрываются подробности о объектно-ориентированной компонентной системе, основанной на принципах ориентированного на данные проектирования, которые, на мой взгляд, актуальны и, возможно, полезны. Тем не менее, я удалил ссылку на удалить любые предвзятости.
Гомер
2

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

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

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

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

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

В результате ECS позволяет очень легко выполнять такие вещи, как замена движка рендеринга OpenGL на DirectX, даже если эти два реализованы с радикально отличающимися функциональными возможностями и не имеют одинаковых конструкций вообще, при условии, что и движок DX, и GL иметь доступ к таким же стабильным данным. Между тем это было бы очень дорого и потребовало бы переписывания нескольких систем для изменения, скажем, представления данных a MotionComponent.

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

И в моем случае, по крайней мере, SDK ECS с API и всеми компонентами фактически реализован на C и не имеет никакого сходства с ООП. Я нашел C более чем достаточным для такой цели, учитывая присущий ей недостаток OO в архитектурах ECS и желание иметь архитектуру плагинов, которая может использоваться самым широким диапазоном языков и компиляторов. Системы по-прежнему реализованы на C ++, поскольку C ++ делает их там очень удобными, и системы моделируют большую часть сложности, и там я нахожу применение многим вещам, которые можно рассматривать ближе к ООП, но это для деталей реализации. Сам архитектурный проект все еще напоминает очень процедурный С.

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


источник