इवेंट शेड्यूलर के लिए सिंगलटन पैटर्न से कैसे बचें?


13

मैं अपने गेम के लिए एक इवेंट शेड्यूलर बनाना चाहता हूं, मैं मूल रूप से गेम इवेंट के ट्रिगर को शेड्यूल करने में सक्षम होना चाहता हूं। यह एक बार ट्रिगर हो सकता है, या एक आवधिक ट्रिगर (5 सेकंड के सेकंड पर "E_BIG_EXPLOSION" ट्रिगर घटना हो सकती है ...)।

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

इस मामले में सिंगलटन के उपयोग से बचने के लिए आप किस डिजाइन का प्रस्ताव रखेंगे?


इस उत्तर को सिंगलटन के विकल्प पर देखें
BlueRaja - Danny Pflughoeft

जवाबों:


12

आपके पास संदेशों को प्रसारित करने या प्राप्त करने की अनुमति देने वाले इंटरफेस का एक बहुत अच्छी तरह से परिभाषित सेट होना चाहिए - उन्हें एक EventScheduler का संदर्भ देते हुए तुच्छ होना चाहिए। यदि ऐसा नहीं है, या यदि आप ऐसा महसूस करते हैं कि इवेंट शेड्यूलर को "बहुत सारे" प्रकारों में पास करना शामिल है, तो आपके हाथों पर एक बड़ी डिज़ाइन समस्या हो सकती है (एक आश्रित निर्भरता, जिसे सिंग्लेटन्स छूटना चाहते हैं, हल नहीं। )।

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

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

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

class CollisionResponderFactory {
  public CollisionResponderFactory (EventScheduler scheduler) {
     this.scheduler = scheduler;
  }

  CollisionResponder CreateResponder() {
    return new CollisionResponder(scheduler);
  }

  EventScheduler scheduler;
}

class CollisionResponder {
  public CollisionResponder (EventScheduler scheduler) {
    this.scheduler = scheduler;
  }

  public void OnCollision(GameObject a, GameObject b) {
    if(a.IsBullet) {
      scheduler.RaiseEvent(E_BIG_EXPLOSION);
    }
  }

  EventScheduler scheduler;
}

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


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

ऐसा करना कठिन है, इस तरह से कि बिना यह जाने कि आपकी कौन सी कक्षाएं शेड्यूलर को ईवेंट भेजती / प्राप्त करती हैं।

मेरे इंजन में, किसी भी गेम इकाई में एक "ईवेंट डिस्पैचर" घटक हो सकता है ...
Mr.Gando

7

एक ईवेंट डिस्पैचर उन मामलों में से एक है जहां एक सिंगलटन दुनिया में सबसे बुरा विचार नहीं है, लेकिन मैं इससे बचने की कोशिश करने के लिए आपकी सराहना करता हूं। आपको यहां कुछ विचार मिल सकते हैं ।


1
धन्यवाद!, हर बार एक सिंगलटन को एक बिल्ली का बच्चा पैदा होता है;)
श्रीमान्गो

3

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

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

हालांकि मुझे यकीन है कि आपके इवेंट सिस्टम के लिए कुछ अन्य आर्किटेक्चर तैयार किए जा सकते हैं, मेरे लिए यह ऐसा लगता है कि इसे खत्म करने के प्रयास की बर्बादी की तरह लगता है, खासकर जब इवेंट सिस्टम का उपयोग करना पहले से ही एक का उपयोग न करने पर एक बड़ी जीत है।

संपादित करें: समय-समय पर ट्रिगर पर भेजे गए किसी विस्फोट घटना के आपके विशिष्ट उदाहरण के रूप में, मुझे संभवतः किसी अन्य वस्तु (जैसे बुर्ज गन या जो उन विस्फोटों का कारण बनता है) में भेजा गया घटनाएँ होंगी और केंद्रीय घटना प्रणाली में नहीं। हालांकि उन घटनाओं अभी भी भेज दिया जाएगा करने के लिए केंद्रीय घटना प्रणाली।

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