Apakah objek arsitektur Sistem Entitas Komponen berorientasi pada definisi?

20

Apakah arsitektur objek Sistem Entitas Komponen berorientasi, menurut definisi? Tampaknya lebih prosedural atau fungsional bagi saya. Pendapat saya adalah bahwa hal itu tidak menghalangi Anda untuk mengimplementasikannya dalam bahasa OO, tetapi itu tidak akan idiomatis untuk melakukannya dengan cara OO yang kukuh.

Sepertinya ECS memisahkan data (E & C) dari perilaku (S). Sebagai bukti :

Idenya adalah untuk tidak memiliki metode permainan yang tertanam dalam entitas.

Dan :

Komponen terdiri dari sekumpulan data minimal yang diperlukan untuk tujuan tertentu

Sistem adalah fungsi tujuan tunggal yang mengambil satu set entitas yang memiliki komponen tertentu


Saya pikir ini bukan berorientasi objek karena sebagian besar menjadi berorientasi objek adalah menggabungkan data dan perilaku Anda bersama-sama. Sebagai bukti :

Sebaliknya, pendekatan berorientasi objek mendorong programmer untuk menempatkan data di tempat yang tidak dapat diakses langsung oleh seluruh program. Sebagai gantinya, data diakses dengan memanggil fungsi-fungsi tertulis khusus, yang biasa disebut metode, yang digabungkan dengan data.

ECS, di sisi lain, tampaknya tentang memisahkan data Anda dari perilaku Anda.

Daniel Kaplan
sumber

Jawaban:

21

pengantar


Sistem entitas-komponen adalah teknik arsitektur berorientasi objek.

Tidak ada konsensus universal tentang apa arti istilah tersebut, sama dengan pemrograman berorientasi objek. Namun, jelas bahwa sistem entitas-komponen secara khusus dimaksudkan sebagai alternatif arsitektur untuk warisan . Hirarki warisan alami untuk mengekspresikan apa objek yang , tetapi dalam jenis tertentu dari perangkat lunak (seperti game), Anda lebih suka mengungkapkan apa yang obyek tidak .

Ini adalah model objek yang berbeda dari "kelas dan warisan" yang Anda terbiasa bekerja di C ++ atau Java. Entitas sama ekspresifnya dengan kelas, seperti halnya prototipe seperti dalam JavaScript atau Self — semua sistem ini dapat diimplementasikan dalam hal satu sama lain.

 

Contohnya


Katakanlah Mari kita bahwa Playeradalah sebuah entitas dengan Position, Velocity, dan KeyboardControlledkomponen, yang melakukan hal-hal yang jelas.

entity Player:
  Position
  Velocity
  KeyboardControlled

Kita tahu Positionharus dipengaruhi oleh Velocity, dan Velocityoleh KeyboardControlled. Pertanyaannya adalah bagaimana kita ingin memodelkan efek tersebut.

 

Entitas, Komponen, dan Sistem


Misalkan komponen tidak memiliki referensi satu sama lain; Physicssistem eksternal menelusuri semua Velocitykomponen dan memperbarui Positionentitas yang sesuai; suatu Inputsistem menelusuri semua KeyboardControlledkomponen dan memperbarui Velocity.

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

Ini memenuhi kriteria:

  • Tidak ada logika permainan / bisnis yang diungkapkan oleh entitas.

  • Komponen menyimpan data yang menjelaskan perilaku.

Sistem sekarang bertanggung jawab untuk menangani peristiwa dan memberlakukan perilaku yang dijelaskan oleh komponen. Mereka juga bertanggung jawab untuk menangani interaksi antar entitas, seperti tabrakan.

 

Entitas dan Komponen


Namun, anggaplah bahwa komponen lakukan memiliki referensi satu sama lain. Sekarang entitas hanyalah sebuah konstruktor yang menciptakan beberapa komponen, mengikat mereka bersama, dan mengelola masa hidup mereka:

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

Entitas sekarang dapat mengirimkan input dan memperbarui acara langsung ke komponennya. Velocityakan menanggapi pembaruan, dan KeyboardControlledakan menanggapi input. Ini masih memenuhi kriteria kami:

  • Entitas adalah wadah "bisu" yang hanya meneruskan kejadian ke komponen.

  • Setiap komponen memberlakukan perilakunya sendiri .

Di sini, interaksi komponen bersifat eksplisit, tidak dipaksakan dari luar oleh suatu sistem. Data yang menggambarkan perilaku (berapakah jumlah kecepatan?) Dan kode yang memberlakukannya (apa itu kecepatan?) Digabungkan, tetapi dengan cara alami. Data dapat dilihat sebagai parameter untuk perilaku. Dan beberapa komponen tidak bertindak sama sekali — a Positionadalah perilaku berada di suatu tempat .

Interaksi dapat ditangani pada tingkat entitas ("ketika Playerbertabrakan dengan Enemy...") atau pada tingkat komponen individu ("ketika entitas dengan Lifebertabrakan dengan entitas dengan Strength...").

 

Komponen


Apa alasan keberadaan entitas? Jika itu hanya sebuah konstruktor, maka kita dapat menggantinya dengan fungsi mengembalikan seperangkat komponen. Jika nanti kami ingin meminta entitas berdasarkan tipenya, kami juga dapat memiliki Tagkomponen yang memungkinkan kami melakukan hal itu:

function Player():
  t = Tag("Player")
  p = Position()
  v = Velocity(p)
  c = KeyboardControlled(v)
  return {t, p, v, c}
  • Entitas sebodoh itu — mereka hanya set komponen.

  • Komponen merespons langsung ke acara seperti sebelumnya.

Interaksi harus sekarang ditangani oleh query abstrak, benar-benar decoupling acara dari jenis entitas. Tidak ada lagi tipe entitas untuk di-query — Tagdata arbitrer mungkin lebih baik digunakan untuk debugging daripada logika game.

 

Kesimpulan


Entitas bukan fungsi, aturan, aktor, atau kombinator aliran data. Itu adalah kata benda yang mencontohkan fenomena konkret — dengan kata lain, itu adalah objek. Seperti yang dikatakan Wikipedia — sistem entitas-komponen adalah pola arsitektur perangkat lunak untuk memodelkan objek umum.

Jon Purdy
sumber
2
Alternatif utama untuk OO berbasis kelas, OO berbasis prototipe, juga tampaknya berpasangan dengan data dan perilaku. Sebenarnya, tampaknya berbeda dari ECS seperti halnya OO berbasis kelas. Jadi bisakah Anda menguraikan apa yang Anda maksud dengan OO?
Untuk menambahkan pertanyaan @ delnan, apakah Anda tidak setuju dengan cuplikan artikel wikipedia OO yang saya kutip?
Daniel Kaplan
@tieTYT: Kutipan Wikipedia berbicara tentang enkapsulasi dan penyembunyian informasi. Saya tidak berpikir itu bukti bahwa data-perilaku diperlukan, hanya itu umum.
Jon Purdy
@delnan: Saya tidak bermaksud apa-apa oleh OO. Pemrograman berorientasi objek, bagi saya, adalah persis apa yang tertulis di kaleng: pemrograman dengan "objek" (sebagai lawan dari fungsi, aturan, aktor, penggabung aliran data, dll.) Di mana definisi objek tertentu didefinisikan oleh implementasi.
Jon Purdy
1
@tieTYT: Saya baru saja menggambarkan implementasi yang saya lihat di alam liar, untuk menyampaikan bahwa ini adalah istilah yang luas — tidak bertentangan dengan, tetapi tentu saja lebih luas daripada, deskripsi Wikipedia.
Jon Purdy
20

TIDAK. Dan saya terkejut berapa banyak orang yang memilih sebaliknya!

Paradigma

Ini Berorientasi Data alias Data-Driven karena kita berbicara tentang arsitektur dan bukan bahasa yang ditulisnya. Arsitektur adalah realisasi dari gaya pemrograman atau paradigma , yang biasanya dapat secara tidak sengaja bekerja di sekitar dalam bahasa yang diberikan.


Fungsional?

Perbandingan Anda dengan pemrograman Fungsional / Prosedural adalah perbandingan yang relevan dan bermakna. Perhatikan, bagaimanapun, bahwa bahasa "Fungsional" berbeda dari paradigma "Prosedural" . Dan Anda dapat menerapkan ECS dalam bahasa Fungsional seperti Haskell , yang dilakukan orang.


Di mana kohesi terjadi

Pengamatan Anda relevan dan tepat sasaran :

"... [ECS] tidak mencegahmu untuk mengimplementasikannya dalam bahasa OO, tapi itu tidak akan idiomatis untuk melakukannya dengan cara OO yang kukuh"


ECS / ES bukan EC / CE

Ada perbedaan antara arsitektur berbasis komponen, "Entity-Component" dan "Entity-Component-System". Karena ini adalah pola desain yang berkembang, saya telah melihat definisi ini digunakan secara bergantian. Arsitektur "EC" atau "CE" atau "Entity-Component" menempatkan perilaku dalam komponen , sedangkan arsitektur "ES" atau "ECS" menempatkan perilaku dalam sistem . Berikut adalah beberapa artikel ECS, yang keduanya menggunakan nomenklatur menyesatkan, tetapi dapatkan gagasan umum:

Jika Anda mencoba memahami istilah ini di 2015, pastikan referensi seseorang untuk "Sistem Komponen Entitas" tidak berarti "arsitektur Komponen Entitas".

anak anjing
sumber
1
Ini jawaban yang benar. ECS tidak cocok dengan paradigma OOP, karena ECS adalah tentang memisahkan data dan perilaku, sedangkan OOP sebaliknya.
Nax 'vi-vim-nvim'
"sementara OOP adalah tentang kebalikannya" Tidak ada definisi yang diterima tentang apa itu OOP, kecuali definisi akademis yang tidak berguna seperti SmallTalk yang tidak pernah digunakan dalam praktik.
Jean-Michaël Celerier
10

Entity komponen systems (ECSs) dapat diprogram dalam OOP atau secara fungsional tergantung pada bagaimana sistem didefinisikan.

Cara OOP:

Saya telah bekerja pada game di mana entitas adalah objek yang terdiri dari berbagai komponen. Entitas memiliki fungsi pembaruan yang memodifikasi objek pada tempatnya dengan memanggil pembaruan pada semua komponennya secara bergantian. Ini jelas OOP dalam gaya - perilaku terkait dengan data, dan data dapat berubah. Entitas adalah objek dengan konstruktor / destruktor / pembaruan.

Cara yang lebih fungsional:

Alternatifnya adalah agar entitas menjadi data tanpa metode apa pun. Entitas ini dapat ada dalam dirinya sendiri atau hanya menjadi id yang terkait dengan berbagai komponen. Dengan cara ini dimungkinkan (tetapi tidak dilakukan secara umum) untuk berfungsi penuh dan memiliki entitas yang tidak berubah dan sistem murni yang menghasilkan status komponen baru.

Tampaknya (dari pengalaman pribadi) bahwa cara terakhir mendapatkan lebih banyak daya tarik dan untuk alasan yang baik. Memisahkan data entitas dari perilaku menghasilkan kode yang lebih fleksibel dan dapat digunakan kembali (imo). Secara khusus, menggunakan sistem untuk memperbarui komponen / entitas dalam batch dapat lebih berkinerja, dan sepenuhnya menghindari kompleksitas pesan antar-entitas yang mengganggu banyak OOP ECS.

TLDR: Anda bisa melakukannya dengan cara lain, tetapi saya berpendapat bahwa manfaat dari sistem komponen entitas yang baik berasal dari sifatnya yang lebih fungsional.

AGD
sumber
Lebih banyak daya tarik terutama karena seluruh poin komponen adalah untuk menjauh dari hirarki OOP yang sulit diatasi, deskripsi yang baik tentang manfaatnya.
Patrick Hughes
2

Sistem Komponen Entitas Berorientasi Data dapat hidup berdampingan dengan Paradigma Berorientasi Objek: - Sistem Komponen cocok untuk polimorfisme. - Komponen dapat berupa POD (data lama biasa) dan juga JUGA Objek (dengan Kelas dan Metode), dan semuanya masih 'berorientasi data', dengan ketentuan bahwa Metode Kelas Komponen hanya memanipulasi data yang dimiliki oleh objek lokal.

Jika Anda memilih jalur ini, saya sarankan Anda menghindari menggunakan Metode Virtual, karena jika Anda memilikinya, komponen Anda tidak lagi murni komponen data, ditambah metode-metode itu lebih mahal untuk memanggil - ini bukan COM. Jaga kelas komponen Anda bersih dari referensi apa pun untuk apa pun eksternal, sebagai suatu peraturan.

Contohnya adalah vec2 atau vec3, sebuah wadah data dengan beberapa metode untuk menyentuh data itu, dan tidak lebih.

Homer
sumber
2
posting ini agak sulit dibaca (dinding teks). Maukah Anda mengeditnya menjadi bentuk yang lebih baik? Juga, akan membantu jika Anda menjelaskan kepada pembaca mengapa mereka menemukan artikel blog yang terkait bermanfaat dan relevan dengan pertanyaan yang diajukan ...
gnat
... kalau-kalau Anda terkait dengan blog itu (kan?), akan lebih baik juga untuk mengungkapkan afiliasi
nyamuk
Ya, itu adalah blog saya, saya berafiliasi erat dengan blog publik saya, yang mengungkapkan rincian sistem komponen entitas berorientasi objek berdasarkan prinsip-prinsip desain berorientasi data, yang saya percaya relevan dan mungkin berguna, namun saya telah menghapus tautan ke hapus bias apa pun.
Homer
2

Saya menganggap ECS secara fundamental berbeda dari OOP dan cenderung melihatnya dengan cara yang sama dengan Anda, lebih dekat dengan fungsional atau terutama prosedural di alam dengan pemisahan data yang sangat berbeda dari fungsionalitas. Ada juga beberapa kemiripan dengan pemrograman semacam berurusan dengan database pusat. Tentu saja saya orang terburuk dalam hal definisi formal. Saya hanya peduli dengan bagaimana hal-hal cenderung terjadi, bukan apa yang secara konseptual didefinisikan.

Saya mengasumsikan semacam ECS di mana komponen mengumpulkan bidang data dan membuatnya dapat diakses secara publik / global, entitas mengumpulkan komponen, dan sistem menyediakan fungsionalitas / perilaku pada data itu. Itu mengarah ke karakteristik arsitektur yang sangat sulit dari apa yang biasanya kita sebut basis kode berorientasi objek.

Dan tentu saja ada beberapa batas yang kabur dalam cara orang merancang / mengimplementasikan ECS, dan ada perdebatan tentang apa yang sebenarnya merupakan ECS di tempat pertama. Namun batas-batas tersebut juga kabur dalam kode yang ditulis dalam apa yang kita sebut bahasa fungsional atau prosedural. Di antara semua ketidakjelasan ini, konstanta fundamental ECS dengan pemisahan data dari fungsionalitas tampaknya jauh lebih dekat dengan pemrograman fungsional atau prosedural bagi saya daripada OOP.

Salah satu alasan utama yang saya pikir tidak membantu untuk mempertimbangkan ECS untuk menjadi bagian dari kelas OOP adalah bahwa sebagian besar praktik SE terkait dengan OOP berputar di sekitar stabilitas antarmuka publik, dengan fungsi pemodelan antarmuka publik , bukan data. Ide dasarnya adalah bahwa sebagian besar ketergantungan publik mengalir ke fungsi abstrak, bukan ke data konkret. Dan karena itu, OOP cenderung membuatnya sangat mahal untuk mengubah perilaku desain mendasar, sementara membuatnya sangat murah untuk mengubah detail konkret (seperti data dan kode yang diperlukan untuk mengimplementasikan fungsionalitas).

ECS sangat berbeda dalam hal ini mengingat bagaimana hal-hal digabungkan sebagai sebagian besar ketergantungan publik mengalir ke data konkret: dari sistem ke komponen. Akibatnya, setiap praktik SE yang terkait dengan ECS akan berputar di sekitar stabilitas data , karena antarmuka (komponen) yang paling umum dan banyak digunakan sebenarnya hanya data.

Akibatnya, ECS membuatnya sangat mudah untuk melakukan hal-hal seperti mengganti mesin rendering OpenGL untuk yang DirectX, bahkan jika keduanya diimplementasikan dengan fungsi yang sangat berbeda dan tidak berbagi desain yang sama sekali pun, asalkan mesin DX dan GL memiliki akses ke data stabil yang sama. Sementara itu akan sangat mahal dan memerlukan penulisan ulang banyak sistem untuk mengubah, katakanlah, representasi data dari a MotionComponent.

Itu sangat berlawanan dengan apa yang secara tradisional kami kaitkan dengan OOP, setidaknya dalam hal karakteristik penggabungan dan apa yang merupakan "antarmuka publik" vs. "detail implementasi pribadi". Tentu saja dalam kedua kasus "detail implementasi" mudah diubah, tetapi dalam ECS desain data yang mahal untuk diubah (data bukan detail implementasi dalam ECS), dan dalam OOP desain desain fungsionalitas yang mahal untuk diubah (desain fungsi bukan detail implementasi dalam OOP). Jadi itu ide yang sangat berbeda dari "detail implementasi", dan salah satu daya tarik utama bagi saya untuk ECS dari perspektif pemeliharaan adalah bahwa dalam domain saya, data yang diperlukan untuk melakukan banyak hal lebih mudah untuk distabilkan dan dirancang dengan benar sekali dan untuk semua dimuka daripada semua hal yang bisa kita lakukan dengan data itu (yang akan berubah sepanjang waktu ketika klien berubah pikiran dan saran pengguna baru datang membanjir). Akibatnya, saya menemukan biaya pemeliharaan menurun ketika kami mulai mengarahkan ketergantungan dari fungsi abstrak ke data mentah, pusat (tetapi masih dengan hati-hati tentang sistem yang mengakses komponen mana yang memungkinkan mempertahankan invarian hingga tingkat yang waras meskipun semua data secara konseptual sedang dapat diakses secara global).

Dan dalam kasus saya setidaknya, ECS SDK dengan API dan semua komponen sebenarnya diimplementasikan dalam C dan tidak memiliki kemiripan dengan OOP. Saya telah menemukan C lebih dari cukup untuk tujuan seperti itu mengingat kurangnya OO dalam arsitektur ECS dan keinginan untuk memiliki arsitektur plugin yang dapat digunakan oleh berbagai bahasa dan kompiler terluas. Sistem masih diimplementasikan dalam C + + karena C + + membuat hal-hal yang sangat nyaman di sana dan sistem memodelkan sebagian besar kompleksitas dan di sana saya menemukan penggunaan untuk banyak hal yang mungkin dianggap lebih dekat dengan OOP, tapi itu untuk detail implementasi. Desain arsitekturnya sendiri masih sangat mirip dengan C.

Jadi saya pikir agak membingungkan, paling tidak, untuk mencoba mengatakan ECS adalah OO menurut definisi. Paling tidak fundamental melakukan hal-hal yang merupakan pergantian 180 derajat lengkap dari banyak prinsip dasar yang umumnya terkait dengan OOP, dimulai dengan enkapsulasi dan mungkin berakhir dengan apa yang dianggap sebagai karakteristik penggabungan yang diinginkan.


sumber