XNA गेम सर्विसेज और वैश्विक वैरिएबल के बीच क्या अंतर है?


10

Microsoft.Xna.Framework.Gameवर्ग एक है सेवाएं संपत्ति प्रोग्रामर वर्ग के प्रकार और विधि जोड़ने के लिए वर्ग का एक उदाहरण प्रदान करके अपने खेल के लिए एक सेवा को जोड़ने के लिए अनुमति देता है।

अब, AudioComponentसभी वर्गों और विधियों को पास करने की आवश्यकता होती है, बजाय इसके कि आप बस अपना Gameउदाहरण दें और सेवा को देखें। ( सेवा लोकेटर )

अब, क्योंकि खेलों में कई सेवाएं हैं (GraphicsDevice, SceneGraph, AudioComponent, EffectManager, et cetera), अब आप मूल रूप से गेम टू एवरीथिंग पास करेंगे।

तो क्यों न सिर्फ इन उदाहरणों को एक सिंगलटन बनाया जाए? ठीक है, क्योंकि सिंग्लेटन्स खराब हैं क्योंकि उनके पास एक वैश्विक स्थिति है, परीक्षण को रोकना, और अपने डिजाइन को बहुत अधिक भंगुर बनाना। सेवा लोकेटर समान रूप से कई के लिए एक विरोधी पैटर्न माना जाता है क्योंकि केवल एक वस्तु पर निर्भरता पारित करने के बजाय, आप एक सेवा लोकेटर (गेम) पास करते हैं जो कि बाकी सेवाओं के साथ उस वर्ग को जोड़े।

तो फिर XNA और गेम डेवलपमेंट में सेवाओं की सिफारिश क्यों की जाती है? क्या यह इसलिए है क्योंकि खेल नियमित कार्यक्रमों से अलग होते हैं और उनके घटकों के साथ बहुत अधिक जुड़े होते हैं और कक्षा के कामकाज के लिए आवश्यक हर घटक को पारित करना अत्यधिक बोझिल होगा? क्या गेम सर्विसेज अभी गेम डिज़ाइन में एक आवश्यक बुराई हैं? क्या ऐसे विकल्प हैं जो लंबी पैरामीटर सूची और युग्मन शामिल नहीं करते हैं?


3
"सेवा लोकेटर समान रूप से कई के लिए एक विरोधी पैटर्न माना जाता है" - [उद्धरण वांछित]। स्पष्ट रूप से उनका उपयोग करना जहां आपको उनकी आवश्यकता नहीं है - सभी सॉफ़्टवेयर निर्माणों के बारे में बुरा है - लेकिन मैंने कभी भी सेवा निवासियों को एक एंटी-पैटर्न नामक नहीं सुना है। (दूसरी ओर, मैं उन प्रोग्रामरों से बचने की भी कोशिश करता हूं, जो अपना अधिकतर समय नवीनतम पैटर्न

@JoeWreschnig हालांकि मैं आपसे सहमत हूं कि मैंने कुछ खुदाई की थी और यह पाया: blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
Roy T

2
हां, लेकिन वह आदमी DI का उपयोग करने के बारे में एक किताब बेच रहा है; जाहिर है वह नहीं चाहता कि आप कुछ सरल प्रयोग करें, तो आप उसकी किताब नहीं खरीदेंगे! (सभी गंभीरता से, फाउलर के मूल DI / SL लेख ने इस सटीक विषय को कवर किया - martinfowler.com/articles/… - और उस लड़के के ब्लॉग रेंट में चर्चा के लिए कुछ भी नहीं जोड़ा गया है।)

काश मैं उस लिंक को केवल मार्टिन फाउलर से उत्तर के रूप में पोस्ट कर सकता (हालाँकि यह मेरा सवाल नहीं है)
रॉय टी।

जवाबों:


6

मुझे नहीं लगता कि हर कोई इस बात से सहमत है कि सर्विस लोकेटर खराब हैं। सेवा लोकेटर महत्वपूर्ण कार्यक्षमता को डिकॉप करने का एक तरीका प्रदान करते हैं जो सभी को उनके वास्तविक कार्यान्वयन से चाहिए। सर्विस लोकेटर रन टाइम पर सेवाओं को स्वैप करने का एक तरीका भी प्रदान करते हैं। इसके अलावा, मुझे नहीं लगता कि यह सच है कि आपको हर जगह सेवा लोकेटर के चारों ओर से गुजरना होगा। मुझे लगता है कि आप इसे हर जगह से एक्सेस कर सकते हैं। जबकि ग्लोबल्स वाले एक खेल वर्ग को प्रति फ्रेम लगभग हजार बार (जो खराब प्रदर्शन का कारण होगा) पारित करना होगा।

सेवा लोकेटर और एक वर्ग के बीच अंतर को ग्लोबल्स के साथ थोड़ा और स्पष्ट करने के लिए निम्नलिखित उदाहरण पर विचार करें:

मैं एक गेम बना रहा हूं और एक गेमए क्लास ऑब्जेक्ट का उपयोग करता हूं जिसमें एक वैश्विक चर है: सामग्री लोडर। अब अपने अगले गेम में मैं गेमए क्लास का उपयोग नहीं करना चाहता, लेकिन एक नया गेमबी क्लास बनाना चाहता हूं। अब मुझे फिर से गेमए के ग्लोबल्स को गेमबी में जोड़ना होगा जो अतिरिक्त काम है। इसके अलावा, मैं जिस प्रकार की सामग्री लोडर को कॉन्फ़िगर करना चाहता हूं, उसे कॉन्फ़िगर करना कठिन हो जाता है। कहें कि मेरे पास एक गेम है जो पीसी और एक्सबीओएक्स दोनों पर चलता है। पीसी पर मुझे एक कंटेंट लोडर चाहिए जो 'ओपन फाइल' डायलॉग भी दे सके। जबकि XBOX पर मैं निश्चित रूप से यह नहीं चाहता। एक विन्यास फाइल होने से मैं खेल को आसानी से आधा कर सकता हूं, आसानी से कंटेंट लोडर को बदल सकता हूं, यहां तक ​​कि गेमए क्लास के अलावा कहीं और से, बिना गेमए के ग्लोबल्स को सार्वजनिक किए बिना।

अब विचार करें कि मैं एक सेवा लोकेटर का उपयोग कर रहा हूं। मैं हमेशा इसका इस्तेमाल कर सकता हूं। और यहां तक ​​कि हर तरह की सेवाएं हर समय अलग-अलग हो सकती हैं। यह भी सच है कि मैं उनके कार्यान्वयन के बारे में तब तक परवाह नहीं करूंगा जब तक उनका एक सामान्य इंटरफ़ेस नहीं है। (हालांकि मैं क्लास अस्वेल की तरह एक गेम में इस्तेमाल कर सकता था)।

वैसे भी मुझे लगता है कि आप खेल सेवाओं को बहुत आसान पाएंगे। मुझे पता है कि हर कोई इसका इस्तेमाल करता है। आपकी थोड़ी और मदद करने के लिए। मैंने खेल सेवाओं के चारों ओर एक छोटा सहायक वर्ग बनाया है ताकि आप हर समय बहुत कम कास्टिंग कर सकें: http://roy-t.nl/index.php/2010/08/25/xna-accessing-contentmanager -और-ग्राफिक्सदेविस-कहीं भी-कभी-भी-गेमर्विसेकोएंटर / मैं इसका काफी उपयोग करता हूं।


उत्तर के लिए धन्यवाद। एक ऐसे वर्ग में, जिसे सेवा की आवश्यकता होगी, क्या आप आमतौर पर जब भी आवश्यकता होती है, सेवा के लिए GameServices वर्ग से अनुरोध करते हैं, या क्या आप कक्षा में एक सदस्य चर बनाते हैं और केवल निर्माणकर्ता में सेवा के लिए अनुरोध करते हैं? मुझे लगता है मैं जो पूछ रहा हूं वह कितना धीमा return (T)Instance.GetService(typeof(T));है।
जॉन पोलिक

इसके अलावा, क्या आप GameServices वर्ग के इस कार्यान्वयन के बारे में सोचते हैं? मैंने अनावश्यक सिंगलटन को हटा दिया क्योंकि इसमें ऐसी कोई विशेषताएँ नहीं थीं जो अमूर्त के पास पहले से नहीं थीं। इसके अलावा, मैंने Serviceहर विधि के अंत में निरर्थक प्रत्यय को हटा दिया ।
जॉन पोलिक

इसके अलावा, मुझे लगता है कि इसका कारण यह है कि सेवा AddServiceपद्धति एक प्रकार लेती है ताकि आप सेवा के इंटरफ़ेस को निर्दिष्ट कर सकें। उदाहरण के लिए, Services.AddService(typeof(IGraphicsDeviceManager), graphics);। फिर सेवा को पुनः प्राप्त करते समय आप इंटरफ़ेस को प्रकार के रूप में निर्दिष्ट कर सकते हैं और इसे अपने चुने हुए उपवर्ग में डाल सकते हैं।
जॉन पोलिक

@ जॉनपॉलिक, पहले प्रश्न के लिए। मैं हमेशा इसका अनुरोध करने की कोशिश करता हूं (क्योंकि यह बदल सकता है) लेकिन अगर मुझे वास्तव में हर फ्रेम की जरूरत है तो मैं एक सदस्य चर बनाता हूं। मेरे पास प्रदर्शन के अन्य आंकड़े नहीं हैं, क्योंकि यह मेरे लिए कभी भी अड़चन नहीं है। दूसरा, हाँ यह ठीक लग रहा है :)। और तीसरे के लिए। यह वास्तव में प्रकार के तर्क का कारण है, हालांकि आपको कभी भी पुनः प्राप्त मूल्यों को नीचा दिखाने की आदत नहीं डालनी चाहिए, क्योंकि यह कक्षाओं को सेवा के रूप में स्वैप करने की आपकी क्षमता को नष्ट कर देता है। यदि आप एक IGraphicsDeviceManger नहीं चाहते हैं, लेकिन एक MyGDM तो संभवतः एक नया इंटरफ़ेस बनाएँ।
रॉय टी।

1
ओह, मैंने नहीं देखा कि आपने भी वोट डाला है। यदि आप पहले कास्ट करते हैं, तो निश्चित रूप से यह टाइप करने में सक्षम है :)।
रॉय टी।

5

तो क्यों न सिर्फ इन उदाहरणों को एक सिंगलटन बनाया जाए? ठीक है, क्योंकि सिंग्लेटन्स खराब हैं क्योंकि उनके पास एक वैश्विक स्थिति है, परीक्षण को रोकना, और अपने डिजाइन को बहुत अधिक भंगुर बनाना।

सिंगलेट्स आमतौर पर बहुत सारे उपयोगी लक्षण लेते हैं और उन्हें एक भयानक हाइब्रिड में एक साथ पैकेज करते हैं जो आपको कई चीजें देता है जो आप नहीं चाहते हैं जो भी आप चाहते हैं। (क्या यह 'क्रिएट-ऑन-डिमांड' विशेषताओं था? वैश्विक गुंजाइश? कम से कम एक उदाहरण का प्रवर्तन? कई उदाहरणों का निषेध?)

सेवा लोकेटर समान रूप से कई के लिए एक विरोधी पैटर्न माना जाता है क्योंकि केवल एक वस्तु पर निर्भरता पारित करने के बजाय, आप एक सेवा लोकेटर (गेम) पास करते हैं जो कि बाकी सेवाओं के साथ उस वर्ग को जोड़े।

आप पूरी तरह से युग्मन से बच नहीं सकते। चीजें अन्य चीजों का उपयोग करती हैं और इसके बिना आपका कार्यक्रम कुछ नहीं करता है। तो एकमात्र असली सवाल यह है कि यह किस स्तर पर अमूर्त है।

ऑब्जेक्ट ओरिएंटेशन पर अधिकांश ग्रंथ रचना और एकत्रीकरण के बीच अंतर करते हैं। किसी ऐसी चीज़ के बीच वैचारिक अंतर को जानना महत्वपूर्ण है जो आपके पास है और कुछ ऐसा है जिसके बारे में आप जानते हैं। दुर्भाग्य से अधिकांश आधुनिक भाषाओं में यहाँ स्पष्ट अंतर नहीं है, और किसी वस्तु के संदर्भ में इन बातों का कोई मतलब हो सकता है। (विडंबना यह है कि, C ++ बेहतर काम करता है, यदि आप विभिन्न स्मार्ट पॉइंटर प्रकारों का उपयोग करते हैं।)

जिस तरह से आप अपने कोड में रचना और एकत्रीकरण को स्पष्ट कर सकते हैं, वह कुल वस्तुओं के लिए सेवाओं का उपयोग करके है। सेवाएं एक ऐसा तरीका है जो आपको स्वयं के सामान तक पहुंच प्रदान करने के लिए है, लेकिन जिसका आप उपयोग कर सकते हैं।

तो फिर XNA और गेम डेवलपमेंट में सेवाओं की सिफारिश क्यों की जाती है?

मुझे नहीं लगता कि वे खेल के विकास में सार्वभौमिक रूप से अनुशंसित हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.