2010-08-13 6 views
9

इस बारे में बहुत सारे प्रश्न हैं कि सिंगलेट्स "खराब" हैं और इसके बजाय किस पैटर्न का उपयोग करना है। वे आम तौर पर सिंगलटन डिज़ाइन पैटर्न पर केंद्रित होते हैं, जिसमें कक्षा पर एक स्थिर विधि से सिंगलटन इंस्टेंस को पुनर्प्राप्त करना शामिल है। यह उन प्रश्नों में से एक नहीं है।मैं निर्भरता इंजेक्शन का उपयोग कर रहा हूं: मुझे किस प्रकार के सिंगलेट्स के रूप में बांधना चाहिए?

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

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

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

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

उत्तर

5

मैं सिंगलटन उदाहरणों का उपयोग कर रहा (nhibernate सत्र कारखाने की तरह) या वस्तुओं मैं आवेदन भर में साझा करना चाहते हैं के लिए वस्तुओं को बनाने के महंगा कैश करने के लिए।

यदि अनिश्चितता में मैं ऑब्जेक्ट को हर बार इस्तेमाल किया जाता है और इसे सिंगलटन या "प्रति थ्रेड"/"प्रति अनुरोध"/"प्रति जो भी" के रूप में चिह्नित करता है, केवल तभी यदि आपको वास्तव में आवश्यकता हो।

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

भले ही ऑब्जेक्ट में इस समय कोई स्थिति न हो और साझा करने के लिए बचत हो, फिर भी कोई व्यक्ति बाद में प्रतिक्रिया दे सकता है और उसमें राज्य जोड़ सकता है जिसे विभिन्न वस्तुओं/उदाहरणों के बीच अनजाने में साझा किया जा सकता है।

+0

+1। – StriplingWarrior

0

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

+0

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

+1

ओह, उस स्थिति में, आपके प्रश्न का सही उत्तर देने के लिए और जानकारी होनी चाहिए। यदि पास की गई वस्तुओं में कोई राज्य नहीं है, तो कोई नया उदाहरण बनाने के लिए आवश्यक अतिरिक्त ऑब्जेक्ट संदर्भ को छोड़कर कोई अंतर नहीं है। यदि वे करते हैं, तो यह आपकी आवश्यकताओं और आप क्या होने की उम्मीद पर निर्भर करता है। – gtrak

+0

वस्तुओं में अन्य इंजेक्शन सेवाओं से अलग कोई राज्य नहीं है, जो निजी क्षेत्रों के रूप में संग्रहीत होते हैं। इसलिए हर बार एक सेवा बनने पर 'नया' होने का संभावित रूप से एक बड़ा पेड़ होता है, लेकिन यह इसके बारे में है। – StriplingWarrior

1

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

एक एकल उदाहरण हानिकारक हो सकता है हालांकि यह प्रदर्शन में एक बाधा उत्पन्न कर सकता है क्योंकि आपके पास सेवाओं के मामले में एकाधिक अनुरोधों की एक एकल आवृत्ति है।

+0

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

+1

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

0

जैसा कि Gary's answer में बताया गया है, डीआई का पूरा बिंदु टेस्टेबिलिटी है (आप आसानी से किसी वर्ग के सभी संदर्भों को मॉक कर सकते हैं क्योंकि वे सभी कन्स्ट्रक्टर में सूचीबद्ध हैं), रनटाइम प्रदर्शन नहीं।

आप टीडीडी (टेस्ट ड्राइव विकास) करने के लिए चाहते हैं, है ना?

+0

के रूप में गैरी के जवाब (लिखित इससे पहले कि आप जवाब) पर मेरी टिप्पणी में बताया गया है, और शीर्षक है, और फिर सवाल के शरीर में: * मैं निर्भरता इंजेक्शन * उपयोग कर रहा हूँ। मैं सिंगलटन "पैटर्न" के बारे में नहीं पूछ रहा हूं, बल्कि डीआई कॉन्फ़िगरेशन मॉड्यूल में सिंगलटन बनाम क्षणिक के रूप में मेरी सेवाओं को बाध्य करने का कोई फायदा है या नहीं। – StriplingWarrior

+0

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

+0

क्योंकि मैं डि उपयोग कर रहा हूँ, और सम्मेलन से बाध्यकारी, मैं '.InSingletonScope()' कोड की एक पंक्ति के लिए भले ही मैं निर्भरता इंजेक्शन का उपयोग करने के लिए उन्हें प्रदान करने के लिए जारी रखने के लिए जोड़ सकते हैं, और मेरे भंडार कक्षाओं के सभी जादुई एकमात्र हो जाएगा, कक्षाएं जो उन्हें चाहिए। डी ढांचे के लिए धन्यवाद, कोड की पठनीयता किसी भी तरह से अप्रभावित नहीं होगी। मैं मानता हूं कि प्रदर्शन एक बड़ी चिंता नहीं है, इसलिए मेरा सवाल यह है कि इस निर्णय के दौरान मुझे अन्य चिंताओं को ध्यान में रखना चाहिए या नहीं। पूछे गए प्रश्न का उत्तर देने के लिए – StriplingWarrior

संबंधित मुद्दे