2012-11-17 34 views
12

मैं सिंगल प्लेयर से मल्टीप्लेयर तक एक गेम अपडेट कर रहा हूं। इस मामले में गेम मूल रूप से अधिकांश कक्षाओं के साथ लिखा गया था जिसे एकल इंस्टेंट किया गया था। जैसे वहां एक एकल प्लेयर ऑब्जेक्ट था, एक गेमस्टेट ऑब्जेक्ट इत्यादि। यही है, इनमें से प्रत्येक ऑब्जेक्ट एप्लिकेशन के रूप में तब तक रहता था।ऑब्जेक्ट लाइफसाइक्ल मैनेजमेंट और आईओसी कंटेनर

अब एक से अधिक खिलाड़ी एक बार खेल सकते हैं, मुझे स्पष्ट रूप से एक से अधिक प्लेयर ऑब्जेक्ट, गेमस्टेट ऑब्जेक्ट आदि बनाने में सहायता करने की आवश्यकता है। इस पर काम करने के दौरान मुझे एहसास हुआ है कि अधिकांश वस्तुओं में से तीन में से एक है lifespans:

  1. ऐप का जीवनकाल, उदाहरण के लिए नेविगेशन को संभालने के लिए एक कंडक्टर
  2. प्लेयर का जीवनकाल, उदा। वर्तमान प्लेयर
  3. गेम की आयु, उदाहरण के लिए सेटिंग्सव्यूमोडेल वर्तमान गेम के लिए गेमस्टेट

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

+0

लाइफस्टाइल/जीवनकाल को कॉन्फ़िगर करना आम तौर पर अधिकांश डी कंटेनर का समर्थन होता है। आप किस मंच और डी ढांचे के बारे में बात कर रहे हैं? – Steven

+0

मुझे पता है कि कुछ कंटेनरों को आजीवन प्रबंधन के लिए समर्थन है, लेकिन एक वर्ग की कल्पना करें जो एक आईपलेयर को पैरामीटर के रूप में लेता है (जैसा कि इस वर्ग में कई कक्षाएं होती हैं)। यदि कोई कंटेनर है तो रनटाइम डेटा के लिए फ़ैक्टरी की आवश्यकता के बिना आप इस कक्षा को कैसे पंजीकृत करेंगे? मैंने प्रत्येक जीवन चक्र के लिए अलग कंटेनर बनाने के साथ प्रयोग किया है, लेकिन जीवन भर में चिंताओं के दौरान जब भी विभिन्न टुकड़ों को जोड़ने के लिए संघर्ष कर रहा हूं। –

+0

इस मामले में .NET/C# हालांकि मुझे वास्तव में दिलचस्पी है कि लोग इस डिज़ाइन की समस्या को आम तौर पर कैसे हल करते हैं। विशेष रूप से, मैं किसी दिए गए कंटेनर पर बहुत अधिक भरोसा नहीं करना चाहता क्योंकि यह मेरे द्वारा लक्षित प्रत्येक प्लेटफ़ॉर्म पर उपलब्ध नहीं हो सकता है। –

उत्तर

0

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

0

कई आईओसी कंटेनरों में कस्टम लाइफ-साइकल स्कॉप्स होते हैं जिन्हें आप अपनी इच्छा के अनुसार प्रबंधित कर सकते हैं।

kernel.Bind<IService>().To<Service>().InScope((c, o) => yourCustomeScope); 

जब तक yourCustomeScope चर नहीं बदला है, सेवा वस्तु में से एक एक उदाहरण हर बार गिरी IService के लिए एक अनुरोध प्राप्त करता दिया जाता है: इस प्रकार Ninject में उदाहरण के लिए यदि आप अपने कस्टम जीवन चक्र दायरे को परिभाषित कर सकते हैं । जैसे ही आपका कस्टोमस्कोप वैरिएबल बदलता है, सेवा का एक नया उदाहरण IService के लिए अगले अनुरोध पर बनाया जाएगा। आपका कस्टोमस्कोप वर्तमान प्लेयर इंस्टेंस, गेम ऑब्जेक्ट या कुछ भी जिसे आप सेवा ऑब्जेक्ट के जीवनकाल को बदलना चाहते हैं, इसके संदर्भ परिवर्तन के आधार पर हो सकता है।

हालांकि, जिन वस्तुओं का आपने अभी उल्लेख किया है वे उन सेवाओं की बजाय संस्थाओं की अधिक संभावना है जिनके लिए मुझे नहीं लगता कि इंजेक्शन एक अच्छा विचार है।

0

मेरे अनुभव से कारखानों का दृष्टिकोण सबसे अच्छा काम करता है।

उदाहरण के जीवनकाल को नियंत्रित करने के लिए समर्थन के लिए घबराहट है और सभी कक्षाओं के जीवनकाल आवश्यकताओं और निर्भरताओं, विन्यास के विन्यास और प्रबंधन के लिए प्रयासों की आवश्यकता है। उसी समय कारखानों का उपयोग प्राकृतिक और कोड विशिष्ट है।

proxy factories का उपयोग कर कारखानों (कार्यान्वयन) निर्माण से बचा जा सकता है। कारखानों (इंटरफेस) निर्माण की जरूरतों को और कम करने के लिए आप जेनेरिक तर्कों को वापस लाने वाली फैक्ट्रियां भी प्राप्त कर सकते हैं।

यदि अभी भी बहुत सारी कारखानों की आवश्यकता है तो मैं कोड प्रवाह की समीक्षा करने का सुझाव देता हूं।

0

मुझे लगता है कि यह पिछले जवाबों की कुछ टिप्पणियों का एक हिस्सा है लेकिन मैंने कुछ तर्कों पर थोड़ा विस्तार करने का उदाहरण दिया है।

एक बार जब आप इंजेक्शन ऑब्जेक्ट्स लाइफेंसिंग के प्रबंधन के क्षेत्र में आ जाएंगे, तो शायद आपको इन वस्तुओं के लिए कारखानों का निर्माण करना चाहिए।

अंतर्निहित समस्या यह है कि संरचना जड़ इस बात से अवगत नहीं है कि कॉल के पर्यावरणीय संदर्भ को वस्तु बनाने की आवश्यकता होगी।

मुझे लगता है कि मुझे एक कदम वापस लेना चाहिए और इस बिंदु पर समझा जाना चाहिए।

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

संरचना रूट वह जगह है जहां आप अपने इंटरफेस (आमतौर पर, लेकिन संभवतः ऑब्जेक्ट्स) को उनके प्रत्यारोपण के लिए मानचित्रित करते हैं। आप इस बिंदु पर कन्स्ट्रक्टर को उपलब्ध जानकारी में गुजर सकते हैं। तो आप किसी ऑब्जेक्ट के संदर्भ में पारित कर सकते हैं जिसका जीवनकाल संरचना रूट के निष्पादन के समय चालू है।

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

इस फैक्ट्री विधियों को ठीक करने के लिए आपको कारखाने की कक्षा की आवश्यकता नहीं है, इसके अलावा फैक्ट्री विधि को रेखांकित किया जा सकता है और इसलिए कोड ओवरहेड संरचना मार्ग में ऑब्जेक्ट्स बनाते समय कहीं अधिक नहीं है।

यदि हमारे पास 2 सेवाओं के साथ एक परियोजना है जहां पहली सेवा पहले पर निर्भर है और हम केवल दूसरी सेवा के जीवनकाल को शुरू करना चाहते हैं जब हम पहली सेवा बनाते हैं तो हमारे पास निम्न की तरह कुछ हो सकता है।

 

` 
    public class Service1:IService 
    { 
     private Func<IService>serviceFactoryMethod _Service2Factory; 
     public Service1(Func<IService>service2FactoryMethod) 
     { 
      _Service2Factory=service2FactoryMethod; 
     } 

     public void DoSomethingUsingService2() 
     { 
      var service2=_Service2Factory(); 
      service2.DoSomething(); 
     } 
    } 

    public class MainClass 
    { 
     public void CompositionRoot() 
     { 
      var kernel= new StandardKernel(); 
      kernel.Bind.ToMethod(m=> 
      { 
       return new Service1(m.Kernel.Get<IService2>()); 
      } 
     } 
    } 

` 

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

साइड नोट: कि निनजेक्ट का उपयोग करके आप सेवा जीवन के जीवनकाल को दूर करने के लिए अपने जीवनकाल को प्रबंधित करने के लिए सेवा 2 का दायरा बदल सकते हैं। उदाहरण के लिए, यदि आप जानते थे कि किसी गेम का प्रत्येक उदाहरण अपने धागे पर होता है (ठीक है, यह शायद कुछ हद तक असंभव है), तो आप गेम के लिए इनट्रेडस्स्कोप का उपयोग कर सकते हैं।