क्या खुदरा खेल "नियंत्रण के व्युत्क्रम" और "निर्भरता इंजेक्शन" का उपयोग करते हैं?


30

अधिक मेहनती सॉफ्टवेयर डेवलपर्स में से कई मुझे पता है कि वस्तुओं के संदर्भों को संभालने के लिए नियंत्रण और निर्भरता इंजेक्शन के व्युत्क्रम में बढ़ रहे हैं। एक फ़्लैश खेल के नजरिए से आने से मुझे AAA स्टूडियो के सभी ins और outs पता नहीं है, इसलिए: क्या ये रिटेल गेम की दुनिया में उपयोग किए जाते हैं?


मुझे लगता है कि उस दुनिया में प्रदर्शन सभी के ऊपर मायने रखता है, क्योंकि खराब कोड द्वारा प्रोग्रामर की तुलना में कम प्रदर्शन से अधिक उपयोगकर्ता प्रभावित होंगे।
बार्ट वैन ह्युकेलोम

निर्भरता इंजेक्शन एक घटक-आधारित प्रणाली की तरह लगता है, लेकिन क्या आपके पास एक उदाहरण होगा कि कोई नियंत्रण के उलटा कैसे करेगा?
एडीबी

जैसा कि इस सूत्र में से अधिकांश के बारे में गलत जानकारी दी जा रही है कि IoC
बोरिस कॉल

हाँ, वो करते हैं। वास्तव में, दुर्लभ के बारे में एक बात थी कि वे सी ऑफ थीव्स - youtube.com/watch?v=KmaGxprTUfI&t=1s में अपने परीक्षण को कैसे लागू कर रहे हैं । दुर्भाग्य से उनके पास अवास्तविक इंजन में नियंत्रण के व्युत्क्रम के बारे में कहने के लिए बहुत कुछ नहीं था, हालांकि, मैंने एक परियोजना लिखी है जो यह प्रदर्शित करती है कि यह कैसे काम करती है: github.com/jimmyt1988/UE-Testing
Jimmyt1988

जवाबों:


45

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

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

तो, संक्षिप्त उत्तर: हां, लेकिन उस तरीके से नहीं जैसा आप सोच रहे हैं। कभी-कभी, जब आपको विनिमेय व्यवहार की आवश्यकता होती है, तो आप एक निर्माणकर्ता के पास एक वस्तु में पास होंगे जो नई वस्तु के व्यवहार का हिस्सा निर्धारित करता है। यह इसके बारे में।


5
+1 - मैं इस बात से सहमत हूं कि जावा समुदाय को लगता है कि यह एक बहुत ही सरल विचार है।
क्रिस होवे

4
यह विचार जरूरी नहीं है कि आपको उत्पादन में विभिन्न कार्यान्वयनों की अदला-बदली करनी होगी, लेकिन आप स्वचालित परीक्षण की सुविधा के लिए विशेष कार्यान्वयनों को इंजेक्ट करना चाहते हैं। उस संबंध में, DI / IoC निश्चित रूप से खेलों में उपयोगी हो सकता है, लेकिन आप इसे यथोचित रूप से बंद रखना चाहते हैं। आपको उच्च स्तर पर कुछ एक-समय के सेवा प्रस्तावों से अधिक की आवश्यकता नहीं होनी चाहिए - आप खेल में हर छोटी वस्तु के लिए सेवाओं का समाधान नहीं करना चाहते हैं, और निश्चित रूप से हर फ्रेम या ऐसा कुछ भी नहीं।
माइक स्ट्रोबेल

2
@ थोमस डुफोर: एक परीक्षण की अवधारणा कभी भी कुछ साबित नहीं कर सकती है। यह सिर्फ एक डेटा बिंदु है। आप यह साबित किए बिना 100000 बार टेस्ट पास कर सकते हैं कि यह 100001 रन पर पास हो जाएगा। सबूत विषय की तार्किक विश्लेषण से आता है। मैं तर्क दूंगा कि ये आईओसी कंटेनर और इसी तरह टेस्टिंग को आसान साबित करने की कीमत पर कठिन बनाते हैं, और मेरा मानना ​​है कि यह एक बुरी बात है।
काइलोटन

13
@ कियलोतन एक परीक्षण की अवधारणा कभी भी कुछ भी साबित करने की कोशिश नहीं करती है । यह प्रदर्शित करने की कोशिश करता है कि दिए गए इनपुट के साथ व्यवहार अपेक्षित है। जितना अधिक व्यवहार को सही दिखाया जाता है, उतना ही अधिक आपका विश्वास है कि समग्र कार्य सही है, लेकिन यह कभी भी 100% नहीं है। यह कथन कि एक न्यूनतम इंटरफ़ेस कुछ भी साबित करता है, आकर्षक है।
डैश-टॉम-बैंग

5
@ एलेक्स शियरर: मुझे डर है कि मैं कभी भी यह स्वीकार नहीं कर सकता कि औपचारिक आईओसी कंटेनर प्रणाली का उपयोग करने की आवश्यकता है और आम तौर पर परीक्षण की सुविधा के लिए अतिरिक्त कंस्ट्रक्टर तर्क या फैक्ट्री कक्षाएं बना रहा है, किसी भी तरह से, कोड को बेहतर तथ्यहीन बना सकता है, और निश्चित रूप से नहीं यह शिथिल युग्मित बना रहा है। वास्तव में यह बहुत ज्यादा अतिक्रमण, OOP का एक प्रमुख पहलू है। टीडीडी पर भरोसा करने के बजाय अपने डिजाइन को चलाने के लिए और आशा है कि एक अच्छा परिणाम सामने आता है, लोग सिर्फ पहले स्थान पर ठोस सिद्धांतों का पालन कर सकते हैं।
काइलोटन

17

रणनीति पैटर्न , संरचना , निर्भरता इंजेक्शन , सभी बहुत निकटता से संबंधित हैं।

चूंकि रणनीति पैटर्न डिपेंडेंसी इंजेक्शन का एक रूप है, यदि आप एकता जैसे इंजनों पर एक नज़र डालते हैं उदाहरण के लिए वे इस सिद्धांत से पूरी तरह से आधारित हैं। उनके अवयवों (रणनीति पैटर्न) का उपयोग उनके पूरे इंजन में गहराई से अंतर्निहित है।

घटकों के पुन: उपयोग से अलग मुख्य लाभों में से एक खतरनाक गहरी श्रेणी पदानुक्रम से बचने के लिए है।

यहां मिक वेस्ट का एक लेख है, जो इस बारे में बात करता है कि उसने इस प्रकार की प्रणाली को नेवरसॉफ्ट द्वारा टोनी हॉक श्रृंखला के खेल में कैसे पेश किया।

अपने पदानुक्रम का विकास करें

हाल के वर्षों तक, गेम प्रोग्रामर ने खेल संस्थाओं का प्रतिनिधित्व करने के लिए एक गहरी श्रेणी पदानुक्रम का लगातार उपयोग किया है। ज्वार गहरी पदानुक्रमों के इस उपयोग से विभिन्न प्रकार के तरीकों को स्थानांतरित करना शुरू कर रहा है, जो घटकों के एकत्रीकरण के रूप में एक गेम इकाई वस्तु की रचना करते हैं ...


2
+1, इवोल्व योर हायरार्की एक बेहतरीन कड़ी है जिसके बारे में मैं पूरी तरह से भूल चुका हूँ। स्कॉट बिलास स्लाइड भी अच्छे हैं - इनके लिए सही लिंक ( scottbilas.com/files/2002/gdc_san_jose/game_objects_slides.pdf ) है। एक और संबंधित स्लाइड्स के सेट है, लेकिन मैं जहां भूल गए ...
लिएंडर

इसके अलावा खेल रत्न 5 (मुझे लगता है) में लेख बज़्नेने द्वारा।
क्रिस हॉवे

13

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

class Game {
    void Load() {
        this.Sprite.Load(); // loads resource for drawing later
    }
}

class Sprite {
    void Load() {
        FileReader reader = new FileReader("path/to/resource.gif");
        // load image from file
    }
}

ऊपर यह स्पष्ट है कि Sprite.Loadएक पर निर्भरता है FileReader। जब आप उस विधि का परीक्षण करना चाहते हैं जिसकी आपको आवश्यकता है:

  1. जगह में एक फाइल सिस्टम
  2. फ़ाइल सिस्टम से लोड करने के लिए एक परीक्षण फ़ाइल
  3. सामान्य फ़ाइल सिस्टम त्रुटियों को ट्रिगर करने की क्षमता

पहले दो स्पष्ट हैं, लेकिन अगर आप यह सुनिश्चित करना चाहते हैं कि आपकी त्रुटि हैंडलिंग काम करती है तो उम्मीद है कि आपको वास्तव में # 3 की भी आवश्यकता है। दोनों मामलों में आपने संभावित रूप से अपने परीक्षणों को थोड़ा धीमा कर दिया है क्योंकि उन्हें अब डिस्क पर जाने की आवश्यकता है और आपने अपने परीक्षण वातावरण को अधिक जटिल बना दिया है।

IoC का लक्ष्य इसके निर्माण से व्यवहार के उपयोग को कम करना है। ध्यान दें कि यह रणनीति पैटर्न से कैसे भिन्न है। रणनीति पैटर्न के साथ लक्ष्य व्यवहार के फिर से उपयोग करने योग्य हिस्सा को घेरना है ताकि आप इसे भविष्य में आसानी से बढ़ा सकें; इसके बारे में कुछ नहीं कहना है कि रणनीतियों का निर्माण कैसे किया जाता है।

यदि हम Sprite.Loadऊपर की विधि को फिर से लिखना चाहते हैं तो हम संभवतः समाप्त हो जाएंगे:

class Sprite {
    void Load(IReader reader) {
        // load image through reader
    }
}

अब, हमने इसके उपयोग से पाठक के निर्माण को रोक दिया है। इसलिए, परीक्षण के दौरान परीक्षण रीडर में स्वैप करना संभव है। इसका मतलब है कि आपके परीक्षण वातावरण को अब फ़ाइल सिस्टम, परीक्षण फ़ाइलों की आवश्यकता नहीं है, और आसानी से त्रुटि घटनाओं का अनुकरण कर सकते हैं।

ध्यान दें कि मैंने अपने पुनर्लेखन में दो चीजें कीं। मैंने एक इंटरफ़ेस बनाया, IReaderजिसने कुछ व्यवहार को समझाया - यानी स्ट्रैटेजी पैटर्न को लागू किया। इसके अलावा, मैंने दूसरे वर्ग के लिए सही पाठक बनाने की ज़िम्मेदारी निभाई।

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


2
एलेक्स: कोई भी पहले से निर्मित वस्तुओं में जहां आवश्यक हो वहां कस्टम कार्यक्षमता को चलाने के लिए आपत्ति कर रहा है। हर कोई ऐसा करता है, जैसे आपके उदाहरण में। समस्या यह है कि लोग पूरे ढांचे का उपयोग कर रहे हैं जो इस सामान को संभालने के लिए विशुद्ध रूप से मौजूद हैं, और धार्मिक रूप से इस कार्यक्षमता पर निर्भर करने के लिए कार्यक्षमता के हर पहलू को कोड करते हैं। वे पहले यूरिया को स्प्राइट निर्माण के लिए एक पैरामीटर के रूप में जोड़ते हैं, और फिर इसे समाप्त करने के लिए विशेष स्प्राइटविलेफाइलरएडरफाइटर ऑब्जेक्ट्स की आवश्यकता होती है, आदि। यह रवैया जावा से उत्पन्न होता है और स्प्रिंग आईओसी कंटेनर, आदि की तरह चीजें होती हैं।
Kylotan

2
लेकिन हम IoC कंटेनरों के बारे में बात नहीं कर रहे हैं - कम से कम मैं इसे मूल पोस्ट में नहीं देखता। हम केवल पैटर्न के बारे में बात कर रहे हैं। आप तर्क कर रहे हैं, जैसा कि सबसे अच्छा मैं बता सकता हूं, "क्योंकि जंगली में कुछ उपकरण खराब हैं, हमें अंतर्निहित अवधारणाओं का उपयोग नहीं करना चाहिए।" यह मुझे स्नान पानी के साथ बच्चे को बाहर फेंकने के रूप में हमला करता है। सादगी के बीच सही संतुलन बनाना, चीजों को हासिल करना, और परियोजना के आधार पर किसी प्रोजेक्ट पर इलाज किए जाने की सबसे बड़ी समस्या है।
एलेक्स शियरर

मुझे संदेह है कि बहुत से लोग
IoC के

4

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


2
सटीक होने के लिए मुझे किसी भी कोड के लिए व्यावहारिक दंड की चिंता होगी जिसे कई बार फ्रेम कहा जाता है। यह निम्न-स्तर हो सकता है या नहीं।
दसपंच

4

इस पर Kylotan के साथ सहमत होना होगा। "निर्भरता इंजेक्शन" एक बदसूरत जावा वैचारिक दोष के लिए एक बदसूरत जावा समाधान है, और केवल किसी को भी अन्य भाषाओं में इसे देखने का एकमात्र कारण है क्योंकि जावा बहुत सारे लोगों के लिए पहली भाषा बन रहा है, जब यह वास्तव में नहीं होना चाहिए।

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

यह एक विचार है जो 1950 के दशक के बाद से है। यह सी मानक पुस्तकालय में है (qsort मन में आता है) और यह जगह में सभी (ईवेंट हैंडलर्स / प्रतिनिधियों) डेल्फी में और .NET। यह पुराने कोड को रीकोड करने के लिए पुराने कोड को नए कोड को कॉल करने में सक्षम बनाता है, और यह गेम इंजन में हर समय उपयोग किया जाता है।


2
मैं भी "तो यह वही था जो लोग उत्साहित हैं?" जब मैं DI के बारे में पढ़ता हूं, लेकिन तथ्य यह है कि अधिकांश गेम प्रोग्रामर इसके बारे में जानने के लिए खड़े हो सकते हैं और इसके बारे में कि यह हमारे द्वारा किए जाने वाले काम पर कैसे लागू होगा।
डैश-टॉम-बैंग

2

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

हालाँकि यह कहा जाना चाहिए कि C ++ में दोनों विधियाँ आभासी तालिकाओं को प्रस्तुत कर सकती हैं जहाँ पहले कोई नहीं था, उनके साथ एक उचित प्रदर्शन हिट लेकर आया।


1

मैं एक पेशेवर खेल देव नहीं हूं, और केवल C ++ में IoC को एक बार लागू करने की कोशिश की है, इसलिए यह सिर्फ अटकलें हैं।

हालांकि, मुझे संदेह है कि खेल डेवलपर्स को IoC के बारे में संदेह होगा क्योंकि इसका मतलब है:

1 / बहुत सारे इंटरफेस और बहुत सी छोटी कक्षाओं को डिजाइन करना

2 / बहुत ज्यादा हर फंक्शन कॉल होने की वजह से हाल ही में

अब, यह एक संयोग हो सकता है, लेकिन दोनों जावा में C ++ में प्रदर्शन के लिए थोड़ा अधिक जटिल और / या समस्याग्रस्त है (जो कि व्यापक रूप से खेल में उपयोग किया जाता है, है न?) है, जहां IoC व्यापक हो गया (शायद क्योंकि ऐसा करना अपेक्षाकृत आसान था, लोगों को हिरण वस्तु पदानुक्रमों को डिजाइन करने में मदद करना, और क्योंकि कुछ लोगों का मानना ​​था कि यह जावा में एक एप्लिकेशन को XML में एक एप्लिकेशन लिखने में बदल सकता है, लेकिन यह एक और बहस है: पी)

मुझे टिप्पणियों में दिलचस्पी है अगर इसका कोई मतलब नहीं है;)

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