КОП. Компонентно-орієнтований підхід

Здарова.

Чули або не чули про КОП — неважливо. Зараз розберемось

У цій статті:

  • що таке КОП на людській мові
  • чому це не ООП і не ECS, але трохи і того, і того
  • як я це використовую на практиці
  • і де цей підхід починає сос@ти, а не бути «красивим»

Без теорії заради теорії. Поїхали

Що таке КОП

КОП — Component-Oriented Programming

Або по-нашому: компонентно-орієнтований підхід

Він сидить десь між:

  • ООП (бо об’єкти, інкапсуляція, життя в MonoBehaviour)
  • ECS (бо розбиваємо логіку на дрібні незалежні шматки)

Тобто так, не риба не м’ясо. І саме в цьому його плюс

В чому ідея

У реальних проєктах:

  • логіка постійно повторюється
  • PlayerController розростається до 2к рядків
  • ворог, NPC і гравець мають 70% однакового коду

І тут приходить проста думка:

А навіщо нам PlayerController, якщо гравець — це просто набір функціоналу?

Розбиваємо на компоненти:

  • Mover
  • Input
  • Attack
  • Health
  • що завгодно

Компонент = окремий функціонал, який може жити сам

Чому не ECS

Логічне питання:

Якщо вже розбивати — то чого не ECS?

Бо ECS це:

  • інше мислення
  • дані окремо, логіка окремо
  • адаптери до MonoBehaviour
  • більший оверхед, ніж вигода в малих/середніх проєктах

А тепер питання:

Нащо?

Unity і так живе на компонентах

Додав Rigidbody — отримав фізику

Ніхто не змушує тебе створювати PhysicsControllerFactory

КОП дозволяє:

  • лишитись у звичному Unity API
  • не ламати мозок ECS-філософією
  • при цьому не писати монолітний клас на все

База термінів (запам’ятай)

Контейнер (Repository)

Обʼєкт, який:

  • зберігає компоненти
  • керує їх життєвим циклом
  • оновлює їх

Компонент

  • одна відповідальність
  • мінімум логіки
  • не знає про існування інших компонентів

Філософія компонента

1. Один компонент — одна відповідальність

Без «і рух, і атака, і UI, і трішки магії»

2. Plug-n-play

Компонент:

  • або працює
  • або не працює
  • але не вимагає ще 3 інших компонентів у правильному порядку

3. Мінімум залежностей

Компоненти не повинні напряму залежати один від одного

Не GetComponent<AnotherComponent>() в кожному методі

MonoBehaviour чи ні

Можна і так, і так

Але без MonoBehaviour:

  • більше контролю
  • простіший інжект
  • легше тестувати
  • легше розширювати

Unity залишається як адаптер, а не центр всесвіту

Мій підхід

Інтерфейси компонентів

  • IComponent — маркер
  • ITickableComponent — Update
  • IFixedTickableComponent — FixedUpdate
  • ILateTickableComponent — LateUpdate
  • IPlayableComponent — Play / Stop / Active
  • IDestroyableComponent — Dispose / OnDestroy

Компонент реалізує тільки те, що йому реально потрібно

ComponentRepository

Один клас, який:

  • зберігає всі компоненти
  • викликає Tick, FixedTick, Play
  • дозволяє отримати компонент по типу

Це твій локальний «міні-движок»

Приклади з репозиторіїв

Тут не абстракція заради абстракції, а реальні кейси:

  • Ворог, який іде до таргету і атакує
  • Рух по драбині
  • HealthBar

Repo:

github.com/...​Sviatenko/ComponentSystem

Варіант з MonoBehaviour трішки інша реалізація, але показано як виглядають компоненти:

github.com/...​AndriiSviatenko/FPS_Melee

Коли КОП НЕ підходить

Бо магії не існує

КОП буде проблемою, якщо:

  • потрібна жорстка оптимізація на тисячі ентіті
  • важливий чіткий data-oriented підхід
  • логіка сильно залежить від порядку виконання
  • проєкт переростає в «ECS, але ми соромимось»

Тоді або нормальний ECS, або чесний моноліт. Без лицемірства

Фінал

КОП — не срібна куля

Але це адекватний компроміс між:

  • чистотою архітектури
  • швидкістю розробки

Все

Можеш ставити прочерк над «я не знаю що таке КОП»

Пока.

Підписуйтеся на Telegram-канал @gamedev_dou, щоб не пропустити найважливіші статті і новини про геймдев

👍ПодобаєтьсяСподобалось1
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Хтось забув промпт перетворити на текст ))

Що я тільки що прочитав ?

Поздравляем! Ачивка «Декомпозиция» разблокирована

Підписатись на коментарі