ความแตกต่างระหว่าง XNA Game Services และตัวแปรทั่วโลกที่ได้รับเกียรติคืออะไร?


10

Microsoft.Xna.Framework.Gameชั้นมีบริการสถานที่ให้บริการที่ช่วยให้โปรแกรมเมอร์ที่จะเพิ่มบริการให้กับเกมของพวกเขาโดยการให้ประเภทของชั้นเรียนและเป็นตัวอย่างของชั้นเรียนเพื่อเพิ่มวิธีการ

ตอนนี้แทนที่จะต้องส่งผ่านAudioComponentไปยังคลาสและวิธีการทั้งหมดที่ต้องการแทนคุณเพียงแค่ส่งGameอินสแตนซ์ของคุณและค้นหาบริการ (ตัวระบุบริการ )

ตอนนี้เนื่องจากเกมมีบริการมากมาย (GraphicsDevice, SceneGraph, AudioComponent, EffectsManager และอื่น ๆ ) คุณจะต้องผ่านเกมไปทุกอย่าง

เหตุใดจึงไม่เพียงทำให้อินสแตนซ์เหล่านี้เป็นซิงเกิลล่ะ ดีเพราะ Singletons ไม่ดีเพราะพวกเขามีสถานะทั่วโลกป้องกันการทดสอบและทำให้การออกแบบของคุณเปราะมากขึ้น ตัวระบุตำแหน่งการบริการนั้นได้รับการพิจารณาอย่างเท่าเทียมกันว่าเป็นรูปแบบการต่อต้านต่อคนจำนวนมากเพราะแทนที่จะผ่านการพึ่งพาวัตถุคุณเพียงผ่านตัวระบุตำแหน่งของบริการ (เกม) ซึ่งเป็นคู่รักที่มาพร้อมกับบริการที่เหลือ

เหตุใดจึงแนะนำบริการใน XNA และการพัฒนาเกม เป็นเพราะเกมแตกต่างจากโปรแกรมปกติและมีการผสมผสานอย่างมากกับส่วนประกอบและต้องผ่านทุกองค์ประกอบที่จำเป็นสำหรับการทำงานของคลาสจะยุ่งยากมาก? บริการเกมนั้นเป็นสิ่งชั่วร้ายที่จำเป็นในการออกแบบเกมหรือไม่? มีทางเลือกอื่นที่ไม่เกี่ยวข้องกับรายการพารามิเตอร์ที่มีความยาวและการมีเพศสัมพันธ์หรือไม่?


3
"ผู้ให้บริการได้รับการพิจารณาอย่างเท่าเทียมกันว่าเป็นรูปแบบการต่อต้านต่อคนจำนวนมาก" - [อ้างจำเป็น] เห็นได้ชัดว่าใช้พวกเขาในที่ที่คุณไม่ต้องการพวกเขาจะไม่ดี - จริงของการสร้างซอฟต์แวร์ทั้งหมด - แต่ฉันไม่เคยได้ยินผู้ให้บริการที่เรียกว่ารูปแบบการต่อต้าน (ในทางกลับกันฉันก็พยายามหลีกเลี่ยงโปรแกรมเมอร์ที่ใช้เวลาส่วนใหญ่พูดคุยเกี่ยวกับรูปแบบล่าสุดของ minutiae)

@JoeWreschnig แม้ว่าฉันจะเห็นด้วยกับคุณฉันขุดบางส่วนและพบสิ่งนี้: blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
Roy T.

2
ใช่ แต่ผู้ชายคนนั้นขายหนังสือเกี่ยวกับการใช้ DI; เห็นได้ชัดว่าเขาไม่ต้องการให้คุณใช้สิ่งที่ง่ายแล้วคุณจะไม่ซื้อหนังสือของเขา! (ในทุกกรณีบทความ DI / SL ดั้งเดิมของ Fowler ได้กล่าวถึงหัวข้อที่แน่นอนนี้ - martinfowler.com/articles/ … - และการพูดคุยในบล็อกของผู้ชายคนนั้นไม่ได้เพิ่มการสนทนาเลย)

ฉันหวังว่าฉันจะทำเครื่องหมายการเชื่อมโยงที่คุณเพียงแค่โพสต์จากมาร์ตินฟาวเลอร์เป็นคำตอบ (แม้ว่าจะไม่ได้เป็นคำถามของฉัน)
รอยตัน

คำตอบ:


6

ฉันไม่คิดว่าทุกคนยอมรับว่าตัวระบุบริการไม่ดี ตัวระบุตำแหน่งบริการมีวิธีในการแยกการทำงานที่สำคัญที่ทุกคนต้องการจากการใช้งานจริง ที่ตั้งผู้ให้บริการยังมีวิธีในการแลกเปลี่ยนบริการในเวลาทำงาน นอกจากนี้ฉันไม่คิดว่ามันเป็นความจริงที่คุณต้องผ่านรอบ ๆ ตัวค้นหาบริการทุกที่ ฉันคิดว่าคุณสามารถเข้าถึงได้จากทุกที่ ในขณะที่คลาสเกมที่มีรูปกลมจะต้องผ่านรอบหนึ่งพันครั้งต่อเฟรม (ซึ่งจะทำให้ประสิทธิภาพแย่ลง)

ในการสร้างความแตกต่างระหว่าง service locator และ class ที่มี globals ให้ชัดเจนยิ่งขึ้นลองพิจารณาตัวอย่างต่อไปนี้:

ฉันสร้างเกมและใช้วัตถุคลาส gameA ที่มีตัวแปรทั่วโลก: ตัวโหลดเนื้อหา ในเกมถัดไปของฉันฉันไม่ต้องการใช้คลาส gameA แต่สร้างคลาส gameB ใหม่ ตอนนี้ฉันต้องเพิ่มอีกครั้งของเกมไปยังเกม B ซึ่งเป็นงานพิเศษ นอกจากนี้ยังยากที่จะกำหนดประเภทของตัวโหลดเนื้อหาที่ฉันต้องการ สมมติว่าฉันมีเกมที่รันทั้งบนพีซีและบน XBOX บนพีซีฉันต้องการตัวโหลดเนื้อหาที่สามารถเปิดกล่องโต้ตอบ 'เปิดไฟล์' ได้ ในขณะที่ XBOX ฉันไม่ต้องการสิ่งนี้แน่นอน การมีไฟล์ปรับแต่งฉันสามารถทำให้เกมเปลี่ยนเนื้อหาตัวโหลดได้อย่างง่ายดายแม้แต่ครึ่งทางจากที่อื่นในระดับ gameA โดยไม่ต้องทำให้กลมในเกมสาธารณะทั้งหมด

ตอนนี้ให้พิจารณาฉันใช้ตัวระบุบริการ ฉันสามารถใช้มันต่อไปได้เรื่อย ๆ และแม้กระทั่งบริการประเภทใดที่อาจแตกต่างกันตลอดเวลา มันก็เป็นความจริงที่ว่าฉันจะไม่สนใจเรื่องการนำไปใช้ของพวกเขาตราบใดที่พวกเขามีอินเทอร์เฟซทั่วไป (แม้ว่าฉันจะสามารถใช้มันใน gamA เหมือนคลาสได้เช่นกัน)

อย่างไรก็ตามฉันคิดว่าคุณจะพบว่าบริการเกมมีประโยชน์มาก ทุกคนที่ฉันรู้จักใช้มัน เพื่อช่วยให้คุณออกไปอีกเล็กน้อย ฉันได้สร้างคลาสผู้ช่วยเล็ก ๆ เกี่ยวกับบริการเกมเพื่อให้คุณสามารถทำการคัดเลือกนักแสดงน้อยลงได้ตลอดเวลา: http://roy-t.nl/index.php/2010/08/25/xna-accessing-contentmanager - และ -devicedevice- ทุกที่ทุกเวลา - เกม -ervervececontainer /ฉันใช้มันค่อนข้างมาก


ขอบคุณสำหรับการตอบกลับ. ในคลาสที่ต้องการบริการคุณเพียงแค่ร้องขอคลาส GameServices สำหรับบริการทุกครั้งที่ต้องการหรือคุณสร้างตัวแปรสมาชิกในคลาสและร้องขอบริการเฉพาะใน Constructor หรือไม่ ผมคิดว่าสิ่งที่ผมขอให้เป็นวิธีที่ช้าreturn (T)Instance.GetService(typeof(T));คือ
John Pollick

นอกจากนี้คุณคิดอย่างไรกับการใช้งานคลาส GameServices นี้ ฉันลบซิงเกิลตันที่ไม่จำเป็นออกไปเพราะมันไม่มีคุณสมบัติใด ๆ ที่สิ่งที่เป็นนามธรรมไม่ได้มีอยู่ นอกจากนี้ฉันได้ลบServiceคำต่อท้ายซ้ำซ้อนในตอนท้ายของทุกวิธี
John Pollick

นอกจากนี้ฉันคิดว่าเหตุผลที่AddServiceวิธีการใช้บริการเป็นประเภทเพื่อให้คุณสามารถระบุอินเตอร์เฟซของบริการ ตัวอย่างเช่นServices.AddService(typeof(IGraphicsDeviceManager), graphics);. จากนั้นเมื่อดึงบริการคุณสามารถระบุอินเตอร์เฟซเป็นประเภทและส่งไปยังคลาสย่อยที่คุณเลือก
John Pollick

@JohnPollick สำหรับคำถามแรก ฉันพยายามที่จะขอมันเสมอ (เพราะมันอาจมีการเปลี่ยนแปลง) แต่ถ้าฉันต้องการบางสิ่งบางอย่างจริงๆฉันจะสร้างตัวแปรสมาชิก ฉันไม่มีสถิติประสิทธิภาพมากไปกว่านั้นมันไม่ใช่คอขวดสำหรับฉัน ประการที่สองใช่มันดูดี :) และสำหรับบุคคลที่สาม นั่นเป็นเหตุผลสำหรับอาร์กิวเมนต์ชนิดอย่างไรก็ตามคุณไม่ควรสร้างนิสัยในการดึงค่าที่ลดลงเนื่องจากจะทำลายความสามารถในการสลับคลาสเป็นบริการ หากคุณไม่ต้องการ IGraphicsDeviceManger แต่เป็น MyGDM อาจจะสร้างส่วนต่อประสานใหม่
รอยต.

1
โอ้ฉันไม่เห็นคุณหล่อเหมือนกัน แน่นอนว่ามันสามารถสรุปประเภทถ้าคุณแคสต์ก่อน :)
รอยต.

5

เหตุใดจึงไม่เพียงทำให้อินสแตนซ์เหล่านี้เป็นซิงเกิลล่ะ ดีเพราะ Singletons ไม่ดีเพราะพวกเขามีสถานะทั่วโลกป้องกันการทดสอบและทำให้การออกแบบของคุณเปราะมากขึ้น

โดยทั่วไปแล้วซิงเกิลตันจะใช้คุณสมบัติที่มีประโยชน์มากมายแล้วนำมารวมกันเป็นลูกผสมที่น่ากลัวทำให้คุณมีหลายสิ่งที่คุณไม่ต้องการพร้อมกับสิ่งที่คุณต้องการ (เป็นคุณลักษณะ 'สร้างตามความต้องการ' หรือไม่ขอบเขตทั่วโลกหรือไม่การบังคับใช้อย่างน้อยหนึ่งอินสแตนซ์หรือไม่ห้ามหลายอินสแตนซ์?)

ตัวระบุตำแหน่งการบริการนั้นได้รับการพิจารณาอย่างเท่าเทียมกันว่าเป็นรูปแบบการต่อต้านต่อคนจำนวนมากเพราะแทนที่จะผ่านการพึ่งพาวัตถุคุณเพียงผ่านตัวระบุตำแหน่งของบริการ (เกม) ซึ่งเป็นคู่รักที่มาพร้อมกับบริการที่เหลือ

คุณไม่สามารถหลีกเลี่ยงการแต่งงานทั้งหมด สิ่งต่าง ๆ ใช้สิ่งอื่นโดยที่โปรแกรมของคุณไม่ทำอะไรเลย ดังนั้นคำถามที่แท้จริงเพียงข้อเดียวก็คือระดับของนามธรรม

ข้อความส่วนใหญ่เกี่ยวกับการวางแนววัตถุทำให้ความแตกต่างระหว่างองค์ประกอบและการรวม เป็นสิ่งสำคัญที่จะต้องทราบความแตกต่างทางแนวคิดระหว่างสิ่งที่คุณเป็นเจ้าของและสิ่งที่คุณรู้ น่าเสียดายที่ภาษาสมัยใหม่ส่วนใหญ่ไม่มีความแตกต่างที่ชัดเจนที่นี่และการอ้างอิงถึงวัตถุอาจหมายถึงสิ่งเหล่านี้ (แดกดัน C ++ ทำงานได้ดีกว่าถ้าคุณใช้ตัวชี้สมาร์ทประเภทต่าง ๆ )

วิธีหนึ่งที่คุณสามารถทำให้การจัดองค์ประกอบและการรวมที่ชัดเจนในรหัสของคุณคือการใช้บริการสำหรับวัตถุรวม บริการเป็นวิธีหนึ่งในการให้การเข้าถึงสิ่งที่คุณไม่ได้เป็นเจ้าของ แต่คุณสามารถใช้ได้

เหตุใดจึงแนะนำบริการใน XNA และการพัฒนาเกม

ฉันไม่คิดว่าพวกเขาจะแนะนำในการพัฒนาเกมสากล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.