यह क्या पैटर्न है, और मुझे यह करना चाहिए?


9

मैं as3 में एक गेम बना रहा हूं फ्लैश डेवलप और फ्लैश cs5 का उपयोग करके। सब कुछ ऑब्जेक्ट ओरिएंटेड है। मैं सोच रहा था, क्या मेरे पास एक "गेटवे" वर्ग होना चाहिए, जिसमें अन्य वर्गों के सभी तात्कालिकताओं के लिए एक संपत्ति-संदर्भ है, और मैं इस गेटवे वर्ग को नई वस्तुओं के पास देता हूं, इसलिए उनकी पहुंच हर वर्ग तक है। इस तरह:

 var block:Block = new Block(gateway);

 //In the block class:
 this.gateway.player.setHealth(100);
 //Or:
 this.gateway.input.lock();

क्या यह एक सिंगलटन पैटर्न या कुछ और जैसा है? क्या मुझे ऐसा करना चाहिए?

जवाबों:


13

इसे संदर्भ ऑब्जेक्ट डिज़ाइन पैटर्न कहा जाता है , और यह सिंगलटन पैटर्न से बेहतर है।

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

तो नहीं, यह एक सिंगलटन नहीं है, यह एक सिंगलटन से बेहतर है।

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

उदाहरण के लिए संदर्भों के विभिन्न स्तरों पर विचार करें:

  • GameplayContext - खिलाड़ी, दुश्मन, स्तर ज्यामिति, आदि का मालिक है।
  • InputContext - कीबोर्ड और माउस हैंडल, इनपुट इवेंट आदि का मालिक है।
  • GraphicsContext - बनावट, विंडो हैंडल आदि का मालिक है।
  • GlobalContext - एक GameplayContext, एक GraphicsContext और एक InputContext का मालिक है। यह वह जगह है जहां आप सेवा लोकेटर पैटर्न को लागू करना चाहते हैं , ताकि दूसरों के लिए कुछ संदर्भों को आवश्यकतानुसार स्वैप किया जा सके। और शायद, त्वरित पुनरावृत्ति और परीक्षण के लिए, यह एक वास्तविक वैश्विक चर में होना चाहिए - बस यह महसूस करें कि जब भी आप इसका उपयोग करते हैं, तो आप तकनीकी ऋण का निर्माण कर रहे हैं

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


+1 अच्छा जवाब। गति या थ्रेडिंग चिंताओं में से कुछ वास्तव में इस संदर्भ में लागू नहीं होते हैं (हालांकि ActionScript3 थ्रेडिंग का समर्थन नहीं करता है और बहुत सी गति में सुधार करने वाले तंत्र जो एएस 3 का उपयोग करते समय लागू नहीं होते हैं)।
बुमज़ैक 11

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

0

यह सिंगलटन पैटर्न की तरह नहीं दिखता है। जिस तरह से मैं इसे समझता हूं, आप अपने सभी उदाहरणों के लिए महत्वपूर्ण गेम-ऑब्जेक्ट के संदर्भ में एक ऑब्जेक्ट पास कर रहे हैं।

यदि यह सिंगलटन पैटर्न होगा, तो आपके पास होगा:

AudioManager.getInstance().playSound(XY);

जबकि आपके मामले में आपके पास हो सकता है:

this.gateway.getAudioManager().playSound(XY);

यह मूल रूप से एक ही दिखता है, लेकिन यह वास्तव में नहीं है। यदि आप AudioManagerएक नए (विस्तारित वर्ग) की जगह लेना चाहते हैं ExtendedAudioManager, तो आप सिंगलटन पैटर्न का उपयोग करके एक दीवार से टकराएंगे। आपका गेटवे दृष्टिकोण संभाल लेगा, हालांकि ठीक है।

आपके दृष्टिकोण का दोष यह है कि आपको gatewayहर जगह से गुजरना होगा । सेवा लोकेटर पैटर्न (में जो Wreschnig द्वारा प्रस्तावित इस धागा), अपने "प्रवेश द्वार पैटर्न" के लिए एक अच्छा प्रतिस्थापन की तरह दिखता है।

कभी-कभी यह आसान है कि सरल और सीधी पद्धति के साथ ओवर-डिजाइनिंग चीजों के बजाय इसे चलाया जाए। खासकर जब यह एक छोटी परियोजना या एक प्रोटोटाइप है। शायद आप ऐसा कर सकते हैंgateway एक वैश्विक चर के कुछ प्रकार .. जैसे। Game.gatewayऔर इसके साथ भागो।


-2

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


जब से मैंने यह उत्तर दिया है, तब से यह प्रश्न काफी हद तक बदल गया है, पर्याप्त है कि यह इसे संपादित करने के लिए इसके लायक नहीं लगता है।
ग्रेगरी एवरी-वियर

2
शीर्षक के अलावा, प्रश्न में कुछ भी नहीं बदला।
बंमज़ैक

1
क्या? शीर्षक के अलावा कुछ भी नहीं बदला है। -1
अटैकिंगहोबो

मुझे लगता है कि मैं यहां शीर्षक के बारे में सोच रहा था; मुझे याद है कि मूल शीर्षक कुछ ऐसा है "मुझे यह कैसे करना चाहिए?" यह पूरी तरह से संभव है कि जब मैंने उत्तर दिया तो मैंने शुरुआती शीर्षक / प्रश्न को गलत बताया।
ग्रेगरी एवरी-वियर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.