Чи орієнтований об'єкт архітектури компонентної системи об'єднання за визначенням?


20

Чи орієнтований об'єкт архітектури компонентної системи за визначенням? Мені це здається більш процедурним чи функціональним. На мою думку, це не заважає вам впроваджувати його на мові ОО, але не було б ідіоматичним робити це непохитним способом ОО.

Схоже, 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
Основна альтернатива OO на основі класу, заснована на прототипі, також поєднує дані та поведінку. Насправді, схоже, він відрізняється від ECS так само, як і OO на базі класів. Тож чи могли б ви пояснити, що ви маєте на увазі під ОО?

Щоб додати питання до @ delnan, чи не погоджуєтесь ви з фрагментом статті, яку я цитував OO у Вікіпедії?
Даніель Каплан

@tieTYT: Цитата у Вікіпедії говорить про інкапсуляцію та приховування інформації. Я не думаю, що це доказ того, що потрібна зв'язок між даними та поведінкою, а лише те, що вона є загальною.
Джон Перді

@delnan: Я нічого не маю на увазі під ОО. Як на мене, об'єктно-орієнтоване програмування - це саме те, що написано на тині: програмування з "об'єктами" (на відміну від функцій, правил, акторів, комбінаторів потоків даних тощо), де конкретне визначення об'єкта визначено реалізацією.
Джон Перді

1
@tieTYT: Я просто описував реалізацію, яку я бачив у дикій природі, щоб довести, що це широкий термін - не суперечливий, але, безумовно, ширший, ніж опис Вікіпедії.
Джон Перді

20

НІ. І я здивований, скільки людей проголосували інакше!

Парадигма

Це орієнтована на дані, відома як « Data-Driven», оскільки ми говоримо про архітектуру, а не про мову, на якій написано. Архітектури - це реалізація стилів програмування або парадигм , які, як правило, можна непомітно обробити певною мовою.


Функціональний?

Ваше порівняння з функціональним / процедурним програмуванням є релевантним та змістовним порівнянням. Однак зауважте, що "функціональна" мова відрізняється від парадигми "Процедурна" . І ви можете реалізувати ECS на такій функціональній мові, як Haskell , що це зробили люди.


Там, де відбувається згуртованість

Ваше спостереження є релевантним та точним :

"... [ECS] не заважає вам впроваджувати його на мові ОО, але це не буде ідіоматично робити це непохитним чином OO"


ECS / ES не є ЄС / CE

Існує різниця між архітектурами на основі компонентів, "Entity-Component" та "Entity-Component-System". Оскільки це модель, що розвивається, я бачив, що ці визначення використовуються взаємозамінно. "EC" або "CE" або "Entity-Component" архітектури розміщують поведінку в компонентах , тоді як "ES" або "ECS" архітектури розміщують поведінку в системах . Ось декілька статей ECS, в яких обидва використовують оманливу номенклатуру, але отримуйте загальне уявлення:

Якщо ви намагаєтесь зрозуміти ці терміни у 2015 році, переконайтеся, що хтось із посиланням на "Система компонентів сутності" не означає "архітектуру Entity-Component".


1
Це правильна відповідь. ECS не дуже добре поєднується з парадигмами OOP, оскільки ECS - це розділення даних та поведінки, тоді як OOP - навпаки.
Nax 'vi-vim-nvim'

"в той час як OOP - це навпаки" Існує не прийняте визначення того, про що йдеться, якщо тільки марні академічні визначення, такі як SmallTalk, які ніколи не використовуються на практиці.
Jean-Michaël Celerier

10

Системи компонентної сутності (ECS) можуть бути запрограмовані OOP або функціонально, залежно від того, як визначена система.

Спосіб OOP:

Я працював над іграми, де сутність була об'єктом, що складається з різних компонентів. Суб'єкт має функцію оновлення, яка змінює об'єкт на місці, викликаючи по черзі оновлення всіх його компонентів. Це явно OOP у стилі - поведінка пов'язана з даними, а дані є мутаційними. Суб'єкти - це об'єкти з конструкторами / деструкторами / оновленнями.

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

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

Схоже (з особистого досвіду), що останній спосіб набирає більшої тяги і з розумних причин. Відокремлення даних сутності від поведінки призводить до отримання більш гнучкого та багаторазового використання коду (imo). Зокрема, використання систем для оновлення компонентів / сукупностей у партіях може бути більш ефективним, і повністю уникає складностей міжвідомчих повідомлень, що викликають загрозу багатьох OOS ECS.

TLDR: Ви можете це зробити в будь-якому випадку, але я можу стверджувати, що переваги хороших компонентних систем сутності випливають із їх більш функціонального характеру.


Більше тяги, тим більше, що вся суть компонентів полягала в тому, щоб відійти від непереборних ієрархій ООП, хороший опис переваги.
Патрік Х'юз

2

Компонентні системи, орієнтовані на дані, можуть співіснувати з об'єктно-орієнтованими парадигмами: - Компонентні системи піддаються поліморфізму. - Компоненти можуть бути як POD (звичайні старі дані), так і об'єкти (з класом та методами), і все це все ще "орієнтоване на дані", за умови, що методи класів компонентів маніпулюють лише даними, що належать локальному об'єкту.

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

Прикладом може бути vec2 або vec3, контейнер даних з деякими методами дотику до цих даних, і більше нічого.


2
цю публікацію досить важко читати (стіна тексту). Ви б не хотіли відредагувати його в кращій формі? Крім того, це допоможе, якщо ви поясните читачам, чому вони можуть вважати пов’язану статтю в блозі корисною та відповідною до
gnat

... у випадку, якщо ви якось пов’язані з цим блогом (чи не так?), також хочеться розкрити приналежність
gnat

Так, це мій блог, я тісно пов’язаний із моїм публічним блогом, де розкриваються деталі об'єктно-орієнтованої системи компонентів об'єкта, заснованої на принципах проектування, орієнтованих на дані, які, на мою думку, є актуальними та, можливо, корисними. усунути будь-які упередження.
Гомер

2

Я вважаю, що ECS є принципово відмінним від OOP і схильний бачити його так само, як і ви, як наближення до функціонального або особливо процесуального характеру з дуже чітким відмежуванням даних від функціональності. Існує також деяка подоба до програмування, що стосується центральних баз даних. Звичайно, я найгірша людина, коли мова йде про формальні визначення. Мене хвилює лише те, як виглядають справи, а не те, що вони концептуально визначені.

Я припускаю своєрідний ECS, де компоненти агрегують поля даних і роблять їх загальнодоступними / глобально доступними, сутності агрегують компоненти, а системи забезпечують функціональність / поведінку на цих даних. Це призводить до кардинально складних архітектурних характеристик від того, що ми зазвичай називаємо об'єктно-орієнтованою базою кодів.

І звичайно, є деяка розмитість меж у способі проектування / впровадження системи ECS, і дебати про те, що саме є ECS, в першу чергу. Однак такі межі також розмиті в коді, написаному на тому, що ми називаємо функціональною або процедурною мовою. Серед усієї цієї нечіткості фундаментальна константа ECS з відокремленням даних від функціональності здається мені набагато ближчою до функціонального чи процедурного програмування, ніж OOP.

Однією з головних причин, на яку я не думаю, що корисно вважати, що ECS належить до класу OOP, полягає в тому, що більшість практик SE, пов'язаних з OOP, обертаються навколо стабільності публічного інтерфейсу, з функціями моделювання публічних інтерфейсів , а не даних. Основна ідея полягає в тому, що основна частина суспільних залежностей спрямована на абстрактні функції, а не на конкретні дані. І через це OOP прагне дуже дорого змінити основні дизайнерські поведінки, при цьому дуже дешево змінювати конкретні деталі (наприклад, дані та код, необхідні для реалізації функціональності).

Система ECS докорінно відрізняється в цьому плані, враховуючи, як справи поєднуються в міру того, як основна частина суспільних залежностей протікає до конкретних даних: від систем до компонентів. Як результат, будь-яка практика SE, пов'язана з ECS, буде обертатися навколо стабільності даних , оскільки найбільш загальнодоступні та широко використовувані інтерфейси (компоненти) - це фактично дані.

Як результат, ECS дозволяє дуже легко робити такі речі, як заміна двигуна візуалізації OpenGL на DirectX, навіть якщо вони реалізовані з кардинально різними функціональними можливостями і взагалі не поділяють однакові конструкції за умови використання двигуна DX та GL. мати доступ до тих же стабільних даних. Тим часом це було б дуже дорого і вимагало б переписати купу систем, щоб змінити, скажімо, представлення даних MotionComponent.

Це зовсім протилежне тому, що ми традиційно асоціюємо з OOP, принаймні, з точки зору характеристик зв'язку та того, що являє собою "публічний інтерфейс" та "деталі приватної реалізації". Звичайно, в обох випадках "деталі впровадження" легко змінити, але в ECS - це дизайн даних, які дорого змінювати (дані не є деталізацією щодо впровадження в ECS), а в OOP - це функціональний дизайн, який дорого змінити. (розробка функцій не є деталізацією реалізації в OOP). Тож це зовсім інше уявлення про "деталі реалізації", і одне з головних звернень до мене за системою ECS з точки зору технічного обслуговування полягало в тому, що в моєму домені, Дані, необхідні для того, щоб зробити це було легше стабілізувати та правильно розробити правильно раз і назавжди, ніж усі різні речі, які ми могли зробити з цими даними (що змінюватиметься весь час, коли клієнти передумали, і нові пропозиції користувачів завалилися). Як результат, я виявив, що витрати на обслуговування зменшуються, коли ми почали спрямовувати залежності від абстрактних функцій до необроблених центральних даних (але все ще з обережністю, які системи отримують доступ до яких компонентів, щоб дозволити збереження інваріантів у належному ступені, незважаючи на всі дані, які концептуально є глобально доступні).

І в моєму випадку, принаймні, ECS SDK з API та всі компоненти реально реалізовані в C і не мають подібності з OOP. Я знайшов C більш ніж адекватним для такої мети, враховуючи притаманну відсутність OO в архітектурах ECS та бажання мати архітектуру плагінів, яку можна використовувати для найширшого кола мов та компіляторів. Системи все ще впроваджені в C ++, оскільки C ++ робить там речі дуже зручними, і системи моделюють основну частину складності, і там я знаходжу для багатьох речей, які можна вважати ближчими до OOP, але це для деталей щодо впровадження. Сам архітектурний дизайн все ще нагадує дуже процедурний C.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.