ความกังวลของเขาคือจำนวนชั้นเรียนจำนวนมากจะแปลฝันร้ายบำรุงรักษา มุมมองของฉันคือว่ามันจะมีผลตรงกันข้ามที่แน่นอน
ฉันเป็นเพื่อนของคุณอย่างแน่นอน แต่อาจเป็นเรื่องของโดเมนของเราและประเภทของปัญหาและการออกแบบที่เราจัดการโดยเฉพาะอย่างยิ่งสิ่งที่ประเภทของสิ่งที่น่าจะต้องมีการเปลี่ยนแปลงในอนาคต ปัญหาที่แตกต่างกันวิธีแก้ไขปัญหาที่แตกต่างกัน ฉันไม่เชื่อในสิ่งที่ถูกหรือผิดเพียงแค่โปรแกรมเมอร์พยายามหาวิธีที่ดีที่สุดในการแก้ปัญหาการออกแบบโดยเฉพาะ ฉันทำงานใน VFX ซึ่งไม่เหมือนเครื่องยนต์เกมมากเกินไป
แต่ปัญหาสำหรับฉันที่ฉันต้องดิ้นรนกับสิ่งที่อย่างน้อยก็อาจเรียกได้ว่าเป็นสถาปัตยกรรมที่สอดคล้องกับ SOLID มากกว่า (เป็นแบบ COM) อาจจะถูกต้มลงไปใน "คลาสที่มากเกินไป" หรือ "ฟังก์ชั่นมากเกินไป" เพื่อนของคุณอาจอธิบาย ฉันจะพูดโดยเฉพาะ "การมีปฏิสัมพันธ์มากเกินไปสถานที่มากเกินไปที่อาจทำงานผิดปกติได้หลายแห่งที่อาจทำให้เกิดผลข้างเคียงสถานที่หลายแห่งที่อาจต้องเปลี่ยนและอีกหลายแห่งที่ไม่สามารถทำสิ่งที่เราคิดว่าพวกเขาทำ ."
เรามีอินเทอร์เฟซนามธรรม (และบริสุทธิ์) จำนวนหนึ่งที่นำไปใช้งานโดย boatload ของ subtypes เช่นนั้น (ทำไดอะแกรมนี้ในบริบทของการพูดคุยเกี่ยวกับประโยชน์ของ ECS โดยไม่คำนึงถึงความคิดเห็นด้านล่างซ้าย):
ในกรณีที่อินเทอร์เฟซการเคลื่อนไหวหรืออินเทอร์เฟซโหนดฉากอาจนำมาใช้โดยหลายร้อยชนิดย่อย: ไฟ, กล้อง, ตาข่าย, นักแก้ปัญหาฟิสิกส์, เงา, พื้นผิว, กระดูก, รูปร่างดั้งเดิม, เส้นโค้ง ฯลฯ เป็นต้น (และมักจะมีหลายประเภท ) และปัญหาสุดท้ายคือจริงๆว่าการออกแบบเหล่านั้นไม่เสถียร เรามีการเปลี่ยนแปลงข้อกำหนดและบางครั้งอินเทอร์เฟซเองก็ต้องเปลี่ยนและเมื่อคุณต้องการเปลี่ยนอินเทอร์เฟซแบบนามธรรมที่นำมาใช้โดย subtypes 200 รายการนั่นเป็นการเปลี่ยนแปลงที่มีค่าใช้จ่ายสูงมาก เราเริ่มบรรเทาผลกระทบโดยการใช้คลาสฐานนามธรรมซึ่งช่วยลดค่าใช้จ่ายในการเปลี่ยนแปลงการออกแบบดังกล่าว แต่ยังคงมีราคาแพง
ดังนั้นฉันเริ่มสำรวจสถาปัตยกรรมระบบเอนทิตีส่วนประกอบที่ใช้กันทั่วไปในอุตสาหกรรมเกม ที่เปลี่ยนทุกอย่างเป็นเช่นนี้:
และว้าว! นั่นคือความแตกต่างในแง่ของการบำรุงรักษา การพึ่งพาไม่ได้ไหลไปสู่abstractionsแต่ไปสู่ข้อมูล (ส่วนประกอบ) และในกรณีของฉันอย่างน้อยที่สุดข้อมูลก็มีความเสถียรและง่ายกว่าที่จะได้รับในแง่ของการออกแบบล่วงหน้าแม้จะมีข้อกำหนดที่เปลี่ยนแปลง (แม้ว่าสิ่งที่เราสามารถทำได้กับข้อมูลเดียวกันนั้นเปลี่ยนแปลงตลอดเวลากับข้อกำหนดที่เปลี่ยนแปลง)
นอกจากนี้เนื่องจากเอนทิตีใน ECS ใช้องค์ประกอบแทนการสืบทอดสิ่งเหล่านี้จึงไม่จำเป็นต้องมีฟังก์ชันการทำงาน พวกเขาเป็นเพียง "ภาชนะบรรจุส่วนประกอบ" แบบอะนาล็อก นั่นทำให้มันเป็นแบบอะนาล็อก 200 ชนิดย่อยที่นำอินเตอร์เฟสการเคลื่อนไหวไปใช้งานกลายเป็นอินสแตนซ์ของเอนทิตี 200 รายการ(ไม่ใช่ประเภทที่แยกกันด้วยรหัสแยกต่างหาก) ซึ่งเก็บองค์ประกอบการเคลื่อนไหวเพียงอย่างเดียว A PointLight
จะไม่มีคลาส / ชนิดย่อยที่แยกจากกันอีกต่อไป มันไม่ได้เป็นคลาสเลย มันเป็นตัวอย่างของเอนทิตีที่เพิ่งรวมส่วนประกอบบางอย่าง (ข้อมูล) ที่เกี่ยวข้องกับที่อยู่ในพื้นที่ (การเคลื่อนไหว) และคุณสมบัติเฉพาะของไฟส่องเฉพาะจุด ฟังก์ชั่นเฉพาะที่เกี่ยวข้องกับพวกเขานั้นอยู่ในระบบเช่นRenderSystem
ซึ่งจะมองหาส่วนประกอบของแสงในฉากเพื่อกำหนดวิธีแสดงฉาก
ด้วยความต้องการที่เปลี่ยนแปลงภายใต้วิธีการของ ECS บ่อยครั้งที่มีความจำเป็นต้องเปลี่ยนระบบหนึ่งหรือสองระบบที่ทำงานกับข้อมูลนั้นหรือเพียงแค่แนะนำระบบใหม่ทางด้านข้างหรือแนะนำส่วนประกอบใหม่หากต้องการข้อมูลใหม่
ดังนั้นสำหรับโดเมนของฉันอย่างน้อยและฉันเกือบจะแน่ใจว่าไม่ใช่สำหรับทุกคนสิ่งนี้ทำให้สิ่งต่าง ๆ ง่ายขึ้นมากเพราะการพึ่งพานั้นไหลไปสู่ความมั่นคง (สิ่งที่ไม่จำเป็นต้องเปลี่ยนบ่อย ๆ ) นั่นไม่ใช่กรณีในสถาปัตยกรรม COM เมื่อการพึ่งพานั้นไหลไปสู่ abstractions อย่างสม่ำเสมอ ในกรณีของฉันมันง่ายมากที่จะเข้าใจว่าข้อมูลใดที่จำเป็นสำหรับการเคลื่อนไหวล่วงหน้ามากกว่าสิ่งที่เป็นไปได้ทั้งหมดที่คุณสามารถทำได้ซึ่งมักเปลี่ยนแปลงเล็กน้อยในช่วงหลายเดือนหรือหลายปีที่มีข้อกำหนดใหม่เข้ามา
มีกรณีใน OOP ที่หลักการ SOLID บางส่วนหรือทั้งหมดไม่ได้ยืมตัวเองเพื่อทำความสะอาดรหัสหรือไม่?
รหัสสะอาดฉันไม่สามารถพูดได้เพราะบางคนถือเอารหัสสะอาดกับ SOLID แต่มีบางกรณีที่การแยกข้อมูลออกจากการทำงานเหมือนกับที่ ECS ทำและการเปลี่ยนเส้นทางการพึ่งพาจาก abstractions ไปสู่ข้อมูลทำให้สิ่งต่าง ๆ ง่ายขึ้นมาก การเปลี่ยนแปลงด้วยเหตุผลข้อต่อที่เห็นได้ชัดถ้าข้อมูลจะมีความเสถียรมากกว่านามธรรม แน่นอนว่าการพึ่งพาข้อมูลสามารถทำให้การรักษาค่าคงที่ได้ยาก แต่ ECS มีแนวโน้มที่จะลดระดับนั้นให้น้อยที่สุดด้วยการจัดระเบียบระบบซึ่งจะลดจำนวนระบบที่เข้าถึงคอมโพเนนต์ประเภทใดก็ตาม
ไม่จำเป็นว่าการพึ่งพาควรไหลไปสู่ abstractions ตามที่กรมทรัพย์สินทางปัญญาแนะนำ การพึ่งพาควรไหลไปสู่สิ่งที่ไม่น่าจะต้องการการเปลี่ยนแปลงในอนาคต นั่นอาจจะใช่หรือไม่ใช่ abstractions ในทุกกรณี
- ใช่มีหลักการออกแบบของ OOP ที่ขัดแย้งกับ SOLID บางส่วน
- ใช่มีหลักการออกแบบของ OOP ที่ขัดแย้งกับ SOLID อย่างสมบูรณ์
ฉันไม่แน่ใจว่า ECS เป็นรสชาติของ OOP จริงหรือไม่ บางคนกำหนดวิธีการนั้น แต่ฉันเห็นว่ามันแตกต่างกันอย่างมากกับลักษณะการมีเพศสัมพันธ์และการแยกข้อมูล (ส่วนประกอบ) จากการทำงาน (ระบบ) และการขาดการห่อหุ้มข้อมูล ถ้ามันถือว่าเป็นรูปแบบของ OOP ฉันคิดว่ามันขัดแย้งกับ SOLID มาก (อย่างน้อยที่สุดความคิดที่เข้มงวดที่สุดของ SRP, การเปิด / ปิด, การทดแทน liskov และกรมทรัพย์สินทางปัญญา) แต่ฉันหวังว่านี่เป็นตัวอย่างที่สมเหตุสมผลของกรณีและโดเมนหนึ่งซึ่งประเด็นพื้นฐานที่สุดของ SOLID อย่างน้อยที่สุดคนทั่วไปจะตีความพวกเขาในบริบทของ OOP ที่เป็นที่รู้จักมากขึ้นอาจจะไม่เกี่ยวข้องกัน
ชั้นเรียนเล็ก
ฉันอธิบายสถาปัตยกรรมของหนึ่งในเกมของฉันซึ่งทำให้เพื่อนของฉันประหลาดใจมีชั้นเรียนขนาดเล็กจำนวนมากและเลเยอร์สิ่งที่เป็นนามธรรมหลายชั้น ฉันเป็นที่ถกเถียงกันอยู่ว่านี่เป็นผลมาจากการที่ฉันมุ่งเน้นไปที่การให้ความรับผิดชอบทุกอย่างเดียวและยังช่วยลดการเชื่อมต่อระหว่างส่วนประกอบ
ECS ท้าทายและเปลี่ยนแปลงมุมมองของฉันเป็นอย่างมาก เช่นเดียวกับคุณฉันเคยคิดว่าความคิดในการบำรุงรักษานั้นมีการดำเนินการที่ง่ายที่สุดสำหรับสิ่งต่าง ๆ ที่เป็นไปได้ซึ่งมีความหมายหลายอย่างและยิ่งไปกว่านั้นคือสิ่งที่พึ่งพาซึ่งกันและกัน (แม้ว่าการพึ่งพาอาศัยกันระหว่างนามธรรม) มันสมเหตุสมผลที่สุดถ้าคุณกำลังซูมเข้าในคลาสหรือฟังก์ชั่นเดียวเพื่อต้องการดูการใช้งานที่เรียบง่ายและตรงไปตรงมาที่สุดและถ้าเราไม่เห็นมันให้ปรับโครงสร้างใหม่และอาจย่อยสลายได้อีก แต่มันอาจเป็นเรื่องง่ายที่จะพลาดสิ่งที่เกิดขึ้นกับโลกภายนอกเพราะเมื่อใดก็ตามที่คุณแบ่งสิ่งที่ค่อนข้างซับซ้อนออกเป็น 2 อย่างหรือมากกว่านั้นสิ่งที่ 2 หรือมากกว่านั้นจะต้องโต้ตอบกันอย่างหลีกเลี่ยงไม่ได้ * (ดูด้านล่าง) ทางหรือบางสิ่งที่อยู่ภายนอกต้องโต้ตอบกับพวกมันทั้งหมด
ทุกวันนี้ฉันพบว่ามีความสมดุลระหว่างความเรียบง่ายของบางสิ่งกับจำนวนสิ่งที่มีและจำนวนปฏิสัมพันธ์ที่ต้องการ ระบบใน ECS มีแนวโน้มที่จะค่อนข้างหนักกับการใช้งานที่ไม่น่ารำคาญในการทำงานกับข้อมูลที่เหมือนPhysicsSystem
หรือหรือRenderSystem
GuiLayoutSystem
อย่างไรก็ตามความจริงที่ว่าผลิตภัณฑ์ที่ซับซ้อนต้องการมีเพียงไม่กี่คนเท่านั้นที่ทำให้ง่ายต่อการถอยกลับและเหตุผลเกี่ยวกับพฤติกรรมโดยรวมของ codebase ทั้งหมด มีบางอย่างอยู่ที่นั่นซึ่งอาจแนะนำว่ามันอาจเป็นความคิดที่ไม่ดีที่จะพึ่งพาด้านข้างของคลาสที่น้อยลงและเป็นกลุ่ม (ยังคงแสดงความรับผิดชอบเอกพจน์เนื้อหา) ถ้านั่นหมายถึงคลาสที่น้อยกว่าในการรักษาและเหตุผล ระบบ.
การติดต่อ
ฉันพูดว่า "การโต้ตอบ" มากกว่า "การแต่งงานกัน" (แม้ว่าการลดการตอบโต้หมายถึงการลดทั้งสองอย่าง) เนื่องจากคุณสามารถใช้ abstractions เพื่อแยกวัตถุคอนกรีตสองชิ้น แต่พวกเขายังคงพูดคุยกัน พวกเขายังสามารถทำให้เกิดผลข้างเคียงในกระบวนการของการสื่อสารทางอ้อมนี้ และบ่อยครั้งที่ฉันพบความสามารถในการให้เหตุผลเกี่ยวกับความถูกต้องของระบบเกี่ยวข้องกับ "การโต้ตอบ" มากกว่า "การมีเพศสัมพันธ์" การลดขนาดการโต้ตอบมีแนวโน้มที่จะทำให้สิ่งต่าง ๆ ง่ายขึ้นมากสำหรับฉันที่จะให้เหตุผลทุกอย่างจากมุมมองของนก นั่นหมายถึงสิ่งที่ไม่ได้พูดคุยกันเลยและจากเหตุผลดังกล่าว ECS ก็มีแนวโน้มที่จะลด "การโต้ตอบ" และไม่ใช่แค่การแต่งงานกันเพื่อลดขั้นต่ำสุด (อย่างน้อยฉันก็ไม่ได้)
ที่กล่าวมานี้อาจเป็นอย่างน้อยบางส่วนฉันและจุดอ่อนส่วนตัวของฉัน ฉันได้พบอุปสรรคที่ใหญ่ที่สุดสำหรับฉันในการสร้างระบบขนาดใหญ่และยังคงมีเหตุผลอย่างมั่นใจเกี่ยวกับพวกเขานำทางพวกเขาและรู้สึกว่าฉันสามารถทำการเปลี่ยนแปลงที่ต้องการใด ๆ ที่อาจเกิดขึ้นได้ทุกที่ในแบบคาดการณ์ได้คือการจัดการของรัฐและทรัพยากร ผลข้างเคียง. มันเป็นอุปสรรคที่ใหญ่ที่สุดที่เริ่มเกิดขึ้นเมื่อฉันไปจาก LOC นับหมื่นไปจนถึง LOC นับแสนจนถึง LOC นับล้านแม้แต่รหัสที่ฉันเขียนด้วยตัวเองอย่างสมบูรณ์ หากสิ่งใดที่ทำให้ฉันช้าลงไปสู่การรวบรวมข้อมูลเหนือสิ่งอื่นใดมันเป็นความรู้สึกที่ฉันไม่สามารถเข้าใจได้ว่าเกิดอะไรขึ้นในแง่ของสถานะแอปพลิเคชันข้อมูลผลข้างเคียง มัน' ไม่ใช่เวลาของหุ่นยนต์ที่ต้องทำการเปลี่ยนแปลงที่ทำให้ฉันช้าลงจนไม่สามารถเข้าใจผลกระทบของการเปลี่ยนแปลงได้อย่างเต็มที่หากระบบเติบโตเกินกว่าความสามารถในใจของฉันที่จะให้เหตุผลเกี่ยวกับเรื่องนี้ และการลดการโต้ตอบนั้นสำหรับฉันแล้ววิธีที่มีประสิทธิภาพมากที่สุดในการอนุญาตให้ผลิตภัณฑ์ขยายขนาดใหญ่ขึ้นด้วยคุณสมบัติที่มากขึ้นโดยที่ฉันไม่ได้ถูกครอบงำด้วยสิ่งเหล่านี้เป็นการส่วนตัวเนื่องจากการลดการโต้ตอบไปยังขั้นต่ำเช่นเดียวกันลดจำนวนสถานที่ แม้อาจเปลี่ยนสถานะแอปพลิเคชันและทำให้เกิดผลข้างเคียงอย่างมาก
มันสามารถเปลี่ยนเป็นแบบนี้ได้ (ซึ่งทุกอย่างในแผนภาพมีฟังก์ชั่นการใช้งานและเห็นได้ชัดว่าสถานการณ์ในโลกแห่งความเป็นจริงจะมีจำนวนวัตถุหลายเท่าหลายเท่าและนี่คือแผนภาพ "ปฏิสัมพันธ์" ไม่ใช่ข้อต่อหนึ่ง ใครจะมี abstractions ในระหว่าง):
... ถึงสิ่งนี้ที่มีเพียงระบบที่มีฟังก์ชั่นการทำงาน (ตอนนี้ส่วนประกอบสีน้ำเงินเป็นเพียงข้อมูลและตอนนี้นี่คือแผนภาพการมีเพศสัมพันธ์):
และมีความคิดที่เกิดขึ้นกับสิ่งเหล่านี้และอาจเป็นวิธีที่จะวางกรอบผลประโยชน์เหล่านี้ในบริบทของ OOP ที่เข้ากันได้ดีกับโซลิดมากขึ้น แต่ฉันยังไม่พบการออกแบบและคำพูดเลยและฉันก็พบว่า ยากเนื่องจากคำศัพท์ที่ฉันใช้ในการขว้างปาสิ่งที่เกี่ยวข้องโดยตรงกับ OOP ฉันพยายามคิดออกมาอ่านคำตอบของผู้คนที่นี่และพยายามทำให้ดีที่สุดเพื่อกำหนดของฉันเอง แต่มีบางสิ่งที่น่าสนใจมากเกี่ยวกับธรรมชาติของ ECS ที่ฉันไม่สามารถวางนิ้วของฉันลงบนนั้นได้อย่างสมบูรณ์ อาจใช้งานได้ในวงกว้างยิ่งขึ้นแม้กับสถาปัตยกรรมที่ไม่ได้ใช้ ฉันหวังว่าคำตอบนี้จะไม่ออกมาในฐานะการส่งเสริม ECS! ฉันเพิ่งพบว่ามันน่าสนใจมากตั้งแต่การออกแบบ ECS ได้เปลี่ยนความคิดของฉันอย่างมาก