स्थैतिक तरीकों के बजाय एक सिंगलटन का उपयोग क्यों करें?


92

मुझे सहायक / उपयोगिता वर्ग के इन सरल सवालों के अच्छे उत्तर कभी नहीं मिले:

मैं स्थैतिक तरीकों का उपयोग करने के बजाय एक सिंगलटन (स्टेटलेस) क्यों बनाऊंगा?

यदि किसी वस्तु की कोई अवस्था नहीं है, तो वस्तु उदाहरण की आवश्यकता क्यों होगी?


के संभावित डुप्लिकेट stackoverflow.com/questions/720744/static-class-and-singleton
माइकल Borgwardt

तब से मत सोचो जब हम 2 अलग-अलग भाषाओँ के बारे में बात करते हैं, इसलिए उत्तर अलग-अलग हो सकते हैं, लेकिन लिंक के लिए धन्यवाद, जावा में "मोनोस्टेट" शब्द कभी नहीं सुना
सेबस्टियन लॉबर

जवाबों:


79

अक्सर, सिंगलटन का उपयोग किसी प्रकार के वैश्विक राज्य को एक आवेदन में पेश करने के लिए किया जाता है। (वास्तव में आवश्यक से अधिक बार, ईमानदार होने के लिए, लेकिन यह एक और समय के लिए एक विषय है।)

हालांकि, कुछ कोने मामले हैं जहां एक स्टेटलेस सिंगलटन भी उपयोगी हो सकता है:

  • आप भविष्य में इसे राज्य के साथ विस्तारित करने की उम्मीद करते हैं।
  • आपको किसी विशेष तकनीकी कारण के लिए ऑब्जेक्ट इंस्टेंस की आवश्यकता है । उदाहरण: C # या जावा स्टेटमेंट के लिए सिंक्रोनाइज़ेशन ऑब्जेक्ट ।
    locksynchronized
  • आपको विरासत की आवश्यकता है, अर्थात, आप एक ही इंटरफ़ेस लेकिन एक अलग कार्यान्वयन का उपयोग करके आसानी से अपने सिंगलटन को दूसरे के साथ बदलने में सक्षम होना चाहते हैं।
    उदाहरण: Toolkit.getDefaultToolkit()जावा में विधि एक सिंगलटन लौटाएगा जिसका सटीक प्रकार सिस्टम आश्रित है।
  • आप संतरी मूल्य के लिए संदर्भ समानता चाहते हैं । उदाहरण: C # में।
    DBNull.Value

27
मैं +1 के साथ जाने वाला हूं, हालांकि वैश्विक राज्यों को पेश करने के लिए IMHO सिंगलटन का दुरुपयोग किया जाता है। एक सिंगलटन का उद्देश्य किसी वस्तु को विश्व स्तर पर उपलब्ध कराना नहीं है, बल्कि यह सुनिश्चित करना है कि एक वस्तु को केवल एक बार ही इंस्टेंट किया जाए। वैश्विक वस्तुएँ एक आवश्यक बुराई हैं। जब तक वास्तव में आवश्यकता नहीं होती है, तब तक किसी को उनका उपयोग नहीं करने की कोशिश करनी चाहिए, क्योंकि वे आम तौर पर कुछ लोगों के साथ, हाईस्टलिंग का नेतृत्व करते हैं। :)
back2dos

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

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

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

@itsbruce: अपने उदाहरण नहीं हैं एकमात्र : खाली सूची सूची वर्ग का एकमात्र संभावित उदाहरण नहीं है, और कोई भी मूल्य ऑप्शन वर्ग का एकमात्र संभावित उदाहरण नहीं है। हालांकि, ऐसे उदाहरण हैं जहां प्रहरी मूल्य एकल हैं , और मैंने अपने उत्तर में एक जोड़ने के लिए स्वतंत्रता ली है। शुक्रिया के लिए धन्यवाद!
हेंजज़ी

37

मैं एक स्टैडलेस सिंगलटन के लिए एक मामले को देख सकता हूं जिसका इस्तेमाल एक स्थैतिक विधि वर्ग के बजाय डिपेंडेंसी इंजेक्शन के लिए किया जा रहा है ।

यदि आपके पास उपयोगिता कार्यों का एक सहायक वर्ग है जो आप सीधे उपयोग कर रहे हैं, तो यह एक छिपी निर्भरता बनाता है; आपका इस पर कोई नियंत्रण नहीं है कि इसका उपयोग कौन कर सकता है, या कहां कर सकता है। एक समान एकल वर्ग उदाहरण के माध्यम से उसी सहायक वर्ग को इंजेक्ट करने से आप यह नियंत्रित कर सकते हैं कि इसका उपयोग कहाँ और कैसे किया जा रहा है, और जब आपकी ज़रूरत हो तो इसे बदल दें / इसे मॉक करें / आदि।

इसे एक एकल उदाहरण बनाना बस यह सुनिश्चित करता है कि आप आवश्यकता से अधिक प्रकार की कोई भी वस्तु आवंटित नहीं कर रहे हैं (क्योंकि आपको केवल कभी एक की आवश्यकता है)।


1
"आपका इस पर कोई नियंत्रण नहीं है कि इसका उपयोग कौन कर सकता है, या कहां कर सकता है।" किसी को इसकी आवश्यकता क्यों होगी?
हग्रावल

1
परीक्षण के उद्देश्य के लिए @ अग्रवाल, आपको इसका मजाक
उड़ाने में

15

वास्तव में मुझे एक और उत्तर मिला है जिसका उल्लेख यहां नहीं किया गया है: स्थिर तरीकों का परीक्षण करना कठिन है।

ऐसा लगता है कि अधिकांश परीक्षण रूपरेखाएँ उदाहरण के तरीकों का मज़ाक उड़ाने के लिए बहुत काम करती हैं, लेकिन उनमें से कई स्थैतिक तरीकों का मजाक नहीं उड़ाते हैं।


2
लेकिन पॉवरमॉक ऐसा करने में सक्षम प्रतीत होता है
सेबस्टियन लॉबर

6

अधिकांश प्रोग्रामिंग लैंग्वेज क्लासेस में बहुत प्रकार के सिस्टम को शामिल किया जाता है। जबकि एक क्लास, अपने स्टैटिक मेथड्स और वेरिएबल्स एक ऑब्जेक्ट है, यह बहुत बार इंटरफ़ेस को लागू नहीं कर सकता है या अन्य क्लासेस का विस्तार नहीं कर सकता है। इस कारण से, इसका उपयोग बहुरूपिक तरीके से नहीं किया जा सकता है, क्योंकि यह दूसरे प्रकार का उपप्रकार नहीं हो सकता है। उदाहरण के लिए, यदि आपके पास एक इंटरफ़ेस है IFooable, जो अन्य वर्गों के कई विधि हस्ताक्षरों के लिए आवश्यक है, तो क्लास ऑब्जेक्ट का StaticFooउपयोग नहीं किया जा सकता है IFooable, जबकि FooSingleton.getInstance()(मान, FooSingletonलागू IFooable) कर सकते हैं ।

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

यदि आप वैश्विक सहायक कार्य प्रदान करने की योजना बनाते हैं, तो स्थैतिक तरीके ठीक काम करेंगे। वर्ग वर्ग के रूप में कार्य नहीं करेगा, बल्कि केवल एक नामस्थान के रूप में। मेरा सुझाव है, आप उच्च सामंजस्य बनाए रखते हैं, या आप अजीब युग्मन मुद्दों के साथ समाप्त हो सकते हैं।

नमस्कार
back2dos


4

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

एक उदाहरण पर विचार करें: java.lang.Runtime जावा में एक सिंगलटन वर्ग है। यह वर्ग प्रत्येक JVM के लिए अलग-अलग कार्यान्वयन की अनुमति देता है। कार्यान्वयन प्रति जेवीएम एकल है। यदि यह वर्ग स्थिर होता, तो हम JVM के आधार पर अलग-अलग कार्यान्वयन नहीं कर सकते।

मुझे यह लिंक वास्तव में मददगार लगा: http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html ?

आशा करता हूँ की ये काम करेगा!!


यह उत्तर वास्तविक दुनिया में एक ठोस उदाहरण को शामिल करने के लिए अच्छा है।
सिस्टमोविच

2

मेरे लिए "वॉट ऑब्जेक्ट स्टेट यूज़ सिंगलटन, वांट फंक्शन यूज़ स्टैटिक मेथड"

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

मैं सिंगलटन केस के लिए सलाह देता हूं, इसे तुरंत लागू करने के बाद हमेशा एक ही राज्य होना चाहिए। इसे न तो क्लोन किया जाना चाहिए, न ही सेट करने के लिए कोई मूल्य प्राप्त करना चाहिए ( फ़ाइल में स्थिर कॉन्फ़िगरेशन को छोड़कर ( जावा में गुण फ़ाइल जैसे )।

PS इन 2 के बीच का प्रदर्शन मिलीसेकंड में भिन्न होता है, इसलिए पहले आर्किटेक्चर पर ध्यान दें ।


1

सिंगलटन स्टेटलेस नहीं है, यह वैश्विक स्थिति रखता है।

कुछ कारण जो मैं सिंगलटन का उपयोग करने के बारे में सोच सकता हूं:

  • मेमोरी लीक से बचने के लिए
  • डेटाबेस अनुप्रयोग में सभी मॉड्यूल के लिए एक ही राज्य प्रदान करने के लिए

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