सिंगलटन के बारे में इतना बुरा क्या है? [बन्द है]


1982

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

स्टैक ओवरफ्लो विशेष रूप से लगता है कि हर कोई इस बात से सहमत है कि सिंग्लेटन्स बुराई हैं। क्यों?

कृपया " तथ्यों, संदर्भों या विशिष्ट विशेषज्ञता " के साथ अपने उत्तरों का समर्थन करें


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

71
उत्तरों में बहुत कुछ 'विपक्ष' है, लेकिन मैं कुछ अच्छे उदाहरणों को भी देखना चाहूंगा, जब पैटर्न अच्छा है, तो इसके विपरीत ...
DGM

50
मैंने कुछ महीने पहले इस विषय पर एक ब्लॉग पोस्ट लिखी थी: jalf.dk/blog/2010/03//- और मुझे इसे एकमुश्त कहने की अनुमति दें। मैं व्यक्तिगत रूप से एक एकल स्थिति के बारे में नहीं सोच सकता जहां एक सिंगलटन सही समाधान है। इसका मतलब यह नहीं है कि ऐसी स्थिति मौजूद नहीं है, लेकिन ... उन्हें दुर्लभ कहना एक समझ है।
jalf

8
@ अदमस्मिथ का मतलब यह नहीं है कि आपके पास है, लेकिन इसका मतलब है कि आप इसे इस तरह एक्सेस कर सकते हैं । और अगर आप इसे उस तरह से एक्सेस करने का इरादा नहीं रखते हैं, तो पहली बार में इसे सिंगलटन बनाने का कोई कारण नहीं है। तो आपका तर्क प्रभावी रूप से है "एक सिंगलटन बनाने में कोई बुराई नहीं है अगर हम इसे सिंगलटन के रूप में नहीं मानते हैं । हाँ, महान। मेरी कार भी प्रदूषित नहीं करती है अगर मैं इसमें ड्राइव नहीं करता हूं। लेकिन तब यह आसान है। मैं वास्तव में एक कार की जरूरत नहीं है): पूर्ण प्रकटीकरण) (; नहीं पहली जगह में एक कार के अधिग्रहण।
jalf

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

जवाबों:


1292

ब्रायन बटन से हटा दिया गया:

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

  2. वे एकल जिम्मेदारी सिद्धांत का उल्लंघन करते हैं : इस तथ्य के आधार पर कि वे अपने स्वयं के निर्माण और जीवनचक्र को नियंत्रित करते हैं।

  3. वे स्वाभाविक रूप से कोड को कसकर युग्मित करने का कारण बनते हैं । यह उन्हें कई मामलों में कठिन नहीं बल्कि परीक्षण के तहत बाहर कर देता है।

  4. वे आवेदन के जीवनकाल के लिए राज्य के चारों ओर ले जाते हैं। परीक्षण के लिए एक और हिट जब से आप एक ऐसी स्थिति के साथ समाप्त हो सकते हैं जहां परीक्षणों को आदेश देने की आवश्यकता होती है जो इकाई परीक्षणों के लिए एक बड़ी संख्या नहीं है। क्यों? क्योंकि प्रत्येक इकाई परीक्षण दूसरे से स्वतंत्र होना चाहिए।


324
मैं आप से असहमत हूं। चूंकि टिप्पणियों को केवल 600 वर्णों की अनुमति है, इसलिए मैंने इस पर टिप्पणी करने के लिए एक ब्लॉग पोस्ट लिखा है, कृपया नीचे दिए गए लिंक को देखें। jorudolph.wordpress.com/2009/11/22/singleton-considerations
जोहान्स रूडोल्फ

61
बिंदु 1 और 4 पर, मुझे लगता है कि सिंगलनेट उपयोगी हैं, और वास्तव में कैशिंग डेटा (विशेष रूप से एक डीबी से) के लिए लगभग एकदम सही है। प्रदर्शन में वृद्धि ने मॉडलिंग इकाई परीक्षणों में शामिल जटिलताओं को दूर किया।
दाई बोक

56
@ दाई बोक: "कैशिंग डेटा (विशेष रूप से डीबी से)" ऐसा करने के लिए प्रॉक्सी पैटर्न का उपयोग करें ...
paxos1977

55
वाह, बढ़िया प्रतिक्रियाएँ। मैंने शायद यहाँ अत्यधिक आक्रामक शब्दों का इस्तेमाल किया है, इसलिए कृपया ध्यान रखें कि मैं एक नकारात्मक रूप से तैयार प्रश्न का उत्तर दे रहा था। मेरा उत्तर 'सिंगल पैटर्न्स' की एक छोटी सूची के रूप में था, जो बुरे सिंग्लटन उपयोग से होती है। पूरा खुलासा; मैं भी समय-समय पर सिंगलेट्स का उपयोग करता हूं। एसओ पर अधिक न्यूट्रल तरीके से पूछे जाने वाले सवाल हैं जो तब के लिए उत्कृष्ट मंच बनाएंगे जब सिंग्लेटन्स को एक अच्छा विचार माना जा सकता है। उदाहरण के लिए, stackoverflow.com/questions/228164/…
जिम बर्गर

21
एक बहुस्तरीय वातावरण में कैशिंग के लिए वे इतने महान नहीं हैं। आप सीमित संसाधन पर लड़ रहे कई थ्रेड्स के साथ आसानी से कैश को हरा सकते हैं। [एक सिंगलटन द्वारा बनाए रखा गया]
14

449

सिंगलेट्स एक (और केवल एक) समस्या का समाधान करते हैं।

संसाधन पर ध्यान दें।

यदि आपके पास कुछ संसाधन हैं

( 1 ) केवल एक ही उदाहरण हो सकता है, और

( 2 ) आपको उस एकल उदाहरण को प्रबंधित करने की आवश्यकता है,

आपको एक सिंगलटन की जरूरत है ।

कई उदाहरण नहीं हैं। एक लॉग फ़ाइल बड़ी है। आप केवल एक लॉग फ़ाइल को छोड़ना नहीं चाहते हैं। आप इसे ठीक से फ्लश, सिंक और बंद करना चाहते हैं। यह एकल साझा संसाधन का एक उदाहरण है जिसका प्रबंधन करना है।

यह दुर्लभ है कि आपको एक सिंगलटन की आवश्यकता है। उनके खराब होने का कारण यह है कि वे एक वैश्विक की तरह महसूस करते हैं और वे GoF डिज़ाइन पैटर्न बुक के पूरी तरह से भुगतान किए गए सदस्य हैं ।

जब आपको लगता है कि आपको एक वैश्विक की आवश्यकता है, तो आप शायद एक भयानक डिजाइन गलती कर रहे हैं।


43
हार्डवेयर भी एक उदाहरण सही है? एंबेडेड सिस्टम में बहुत सारे हार्डवेयर होते हैं जो सिंगलनेट का उपयोग कर सकते हैं - या शायद एक बड़ा? <grin>
जेफ

170
पूर्णतया सहमत। वहाँ बहुत कुछ निर्धारित किया गया है "यह अभ्यास बुरा है" बिना किसी मान्यता के चारों ओर तैरती हुई बात है कि अभ्यास का अपना स्थान हो सकता है। अक्सर, अभ्यास केवल "बुरा" होता है क्योंकि इसका अक्सर दुरुपयोग होता है। जब तक यह उचित रूप से लागू किया जाता है तब तक सिंगलटन पैटर्न के साथ कुछ भी गलत नहीं है।
दामोविसा

53
वास्तविक, सिद्धांत रूप से सिंगलटन बहुत दुर्लभ हैं (और एक प्रिंटर कतार निश्चित रूप से एक नहीं है, और न ही एक लॉग फ़ाइल है - लॉग 4 जी देखें)। अधिक बार नहीं, हार्डवेयर सिद्धांत के बजाय संयोग से एक सिंगलटन है। एक पीसी से जुड़े सभी हार्डवेयर सबसे अच्छे संयोग हैं (कई मॉनिटर, चूहे, प्रिंटर, साउंड कार्ड)। यहां तक ​​कि एक 500 mio $ कण डिटेक्टर संयोग और बजट की कमी से एक सिंगलटन है - जो सॉफ्टवेयर में लागू नहीं होता है, इस प्रकार: एक सिंगलटन। दूरसंचार में, न तो फोन नंबर और न ही भौतिक फोन सिंगलटन हैं (सोचें आईएसडीएन, कॉल सेंटर)।
digitalarbeiter

23
हार्डवेयर में विभिन्न प्रकार के संसाधनों का केवल एक उदाहरण हो सकता है, लेकिन हार्डवेयर सॉफ़्टवेयर नहीं है। कोई कारण नहीं है कि एक विकास बोर्ड पर एक एकल सीरियल पोर्ट को सिंगलटन के रूप में मॉडलिंग की जानी चाहिए। वास्तव में, इसे मॉडलिंग करने से केवल नए बोर्ड को पोर्ट करना कठिन हो जाएगा जिसमें दो पोर्ट हैं!
डैश-टॉम-बैंग

19
तो आप दो समान कक्षाएं लिखेंगे, बहुत सारे कोड को डुप्लिकेट करेंगे, बस इसलिए कि आपके पास दो पोर्टलेट्स हो सकते हैं जो दो पोर्ट का प्रतिनिधित्व कर रहे हैं? कैसे के बारे में सिर्फ दो वैश्विक SerialPort वस्तुओं का उपयोग कर? कैसे के बारे में सभी वर्गों के रूप में हार्डवेयर हार्डवेयर नहीं? और आप सिंगलनेट्स का उपयोग क्यों करेंगे, जो वैश्विक पहुंच भी है? क्या आप चाहते हैं कि आपके कोड का हर फंक्शन सीरियल पोर्ट तक पहुंच सके?
jalf

352

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

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


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

21
कारण "हम" उन पर नीचे देखते हैं कि "हम" बहुत बार उन्हें गलत तरीके से इस्तेमाल करते हुए देखते हैं, और अक्सर भी। "हम" जानते हैं कि उनके पास अपनी जगह है।
बज्कर फ्रायंड-हैन्सन

5
@Phil, आपने कहा "समय-समय पर आप पा सकते हैं कि यह आदर्श समाधान है और इसलिए इसका उपयोग करें"। ठीक है, तो वास्तव में किस मामले में हम एक सिंगलटन उपयोगी पाएंगे?
पचेरियर

22
@ स्पेसर, जब भी सभी निम्न स्थितियाँ रखते हैं: (1) आपको केवल किसी एक चीज़ की आवश्यकता होती है, (2) आपको बड़ी संख्या में विधि कॉलों में एक तर्क के रूप में उस चीज़ को पारित करने की आवश्यकता होती है, (3) आप एक को स्वीकार करने को तैयार हैं हर जगह के आस-पास की चीज़ों को पास न करके अपने कोड के आकार और जटिलता में तत्काल कमी के बदले किसी दिन रिफ्लेक्टर करने का मौका।
एंटीइनोम

18
मुझे नहीं लगता कि यह कुछ भी जवाब देता है, यह सिर्फ यह कहता है कि 'कभी-कभी यह फिट हो सकता है, अन्य समय ऐसा नहीं हो सकता है।' ठीक है, लेकिन क्यों, और कब? मॉडरेशन के तर्क से अधिक इसका उत्तर क्या है ?
गिल्डनस्टर्न

219

Google से Misko Hevery ने इस विषय पर कुछ दिलचस्प लेख दिए हैं ...

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

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

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


8
इस विषय पर मिस्को के लेख इस समय सबसे अच्छी बात हैं।
क्रिस मेयर

22
पहला लिंक वास्तव में एकल के साथ एक समस्या को संबोधित नहीं करता है, बल्कि कक्षा के अंदर एक स्थिर निर्भरता मान रहा है। दिए गए उदाहरण को मापदंडों में पारित करके ठीक करना संभव है, फिर भी अभी भी सिंगलटन का उपयोग करें।
डीजीएम

17
@DGM: वास्तव में - वास्तव में, लेख के 'औचित्य' भाग के बीच एक विशाल तार्किक डिस्कनेक्ट है, और 'सिंगललेट्स कारण हैं' भाग।
हार्पर शेल्बी

1
मिसको का क्रेडिटकार्ड लेख इस पैटर्न के दुरुपयोग का एक चरम उदाहरण है।
एलेक्स

2
दूसरा लेख पढ़ना सिंगलेट्स वास्तव में वर्णित ऑब्जेक्ट मॉडल का हिस्सा है। हालांकि, विश्व स्तर पर सुलभ होने के बजाय ये फैक्ट्री ऑब्जेक्ट्स के लिए निजी हैं।
फ्रूटब्रीक

121

मुझे लगता है कि भ्रम इस तथ्य के कारण है कि लोग सिंगलटन पैटर्न के वास्तविक अनुप्रयोग को नहीं जानते हैं। मैं इस पर जोर नहीं दे सकता। ग्लोबल्स को लपेटने के लिए सिंगलटन एक पैटर्न नहीं है। सिंगलटन पैटर्न का उपयोग केवल यह गारंटी देने के लिए किया जाना चाहिए कि किसी दिए गए वर्ग का एक और केवल एक उदाहरण रन टाइम के दौरान मौजूद है।

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


20
वह एक उदाहरण क्या है, पूरे ऐप में उपलब्ध है? ओह। ग्लोबल । "सिंगलटन ग्लोबल्स लपेटने के लिए एक पैटर्न नहीं है" या तो भोली या भ्रामक है, परिभाषा के अनुसार , पैटर्न एक वैश्विक उदाहरण के चारों ओर एक वर्ग लपेटता है।
cHao

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

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

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

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

72

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

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

तो मूल रूप से:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

बजाय:

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

मेरा मानना ​​है कि इस तरह के पैटर्न को निर्भरता इंजेक्शन कहा जाता है और आमतौर पर एक अच्छी बात मानी जाती है।

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


17
हे, यदि आप हर जगह ऐसा करते हैं, तो आपको हर जगह सिंगलटन के संदर्भ में भी गुजरना होगा, और इस तरह आपके पास कोई एकल नहीं है। :) (जो आम तौर पर एक अच्छी बात है IMO।)
बजरैक फ्रंड-हैन्सन

2
@ BjarkeFreund-Hansen - बकवास, आप किस बारे में बात कर रहे हैं? एक सिंगलटन एक वर्ग का एक उदाहरण है जिसे एक बार संस्थापित किया जाता है। इस तरह के एक सिंगलटन को संदर्भित करना वास्तविक वस्तु की नकल नहीं करता है, यह सिर्फ इसका संदर्भ देता है - आपको अभी भी एक ही वस्तु मिली है (पढ़ें: सिंगलटन)।
एम। मिम्पेन

2
@ M.Mimpen: नहीं, एक राजधानी-एस सिंगलटन (जो कि यहां चर्चा की जा रही है) एक वर्ग का एक उदाहरण है (एक) गारंटी देता है कि केवल एक ही उदाहरण मौजूद होगा, और (बी) वर्ग के माध्यम से पहुँचा जाता है निर्मित वैश्विक पहुंच बिंदु। यदि आपने घोषित किया है कि कुछ भी कॉल नहीं किया जाना चाहिए getInstance(), तो (बी) अब बिल्कुल सच नहीं है।
cHao

2
@ cHao मैं आपका अनुसरण नहीं करता या आप मुझे नहीं समझाते हैं कि मैं किस पर टिप्पणी करता हूं - जो कि बज्जके फ्रंड-हेन्सन को है। Bjarke में कहा गया है कि एक सिंगलटन के कई संदर्भों में कई सिंग्लेटन्स होते हैं। यह निश्चित रूप से सच नहीं है क्योंकि गहरी-प्रतियां नहीं हैं।
एम। मिम्पेन

6
@ एम। मिम्पेन: मैं सिमेंटिक प्रभाव के बारे में अधिक बताने के लिए उनकी टिप्पणी लेता हूं। एक बार जब आप कॉल करते हैं getInstance(), तो आप सिंगलटन पैटर्न और एक साधारण संदर्भ के बीच एक उपयोगी अंतर को प्रभावी ढंग से निकाल लेते हैं। जहां तक ​​बाकी कोड का सवाल है, अकेलेपन अब एक संपत्ति नहीं है। केवल फोन करने वाले getInstance()को यह जानने की जरूरत है या यहां तक ​​कि देखभाल के कितने उदाहरण हैं। केवल एक कॉलर के साथ, यह वर्ग के लिए प्रयास और लचीलेपन में अधिक खर्च करता है, क्योंकि यह कॉलर को केवल एक संदर्भ संग्रहीत करने और पुन: उपयोग करने के लिए एकलता को मज़बूती से लागू करता है।
cHao

69

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

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

एक में कचरा एकत्र पर्यावरण एकमात्र जल्दी से स्मृति प्रबंधन के संबंध में एक मुद्दा बन सकता है।

मल्टी-थ्रेडेड परिदृश्य भी है जहां सिंगलनेट एक अड़चन के साथ-साथ एक सिंक्रनाइज़ेशन मुद्दा बन सकता है।


4
मुझे पता है कि यह कई साल पुराना है। hi @Kimoz u ने कहा: - मेमोरी प्रबंधन के संबंध में सिंगलटन एक मुद्दा बन सकता है। अधिक विस्तार से बताना चाहेंगे कि सिंगलटन और कचरा संग्रहण के संबंध में किस प्रकार की समस्या आ सकती है।
थॉमस

@ किमोज, सवाल पूछ रहा है कि "सिंगलटन पैटर्न अपने आप में समस्या क्यों नहीं है?" और आपने केवल बिंदु को दोहराया है, लेकिन सिंगलटन पैटर्न का एक भी मान्य उपयोग मामला नहीं दिया है।
पचेरियर

@ थोमस, क्योंकि परिभाषा के अनुसार एक सिंगलटन केवल एक उदाहरण में मौजूद है। तो, यह अक्सर केवल अशक्त करने के लिए संदर्भ निर्दिष्ट करने के लिए जटिल है। यह किया जा सकता है, लेकिन इसका मतलब है कि आप उस बिंदु को पूरी तरह से नियंत्रित करते हैं जिसके बाद आपके ऐप में सिंगलटन का उपयोग नहीं किया जाता है। और यह दुर्लभ है, और आमतौर पर सिंगलटन जोश की तलाश में काफी विपरीत है: एकल उदाहरण को हमेशा सुलभ बनाने का एक सरल तरीका । कुछ DI फ्रैमवर्क्स जैसे कि गुईस या डैगर, एक सिंगलटन से छुटकारा पाना संभव नहीं है और यह हमेशा के लिए स्मृति में रहता है। (हालांकि कंटेनर प्रदान की गई एकलियां घर के बने सामानों की तुलना में कहीं बेहतर हैं)।
Snicolas

54

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


9
यह इकाई परीक्षण के साथ एक समस्या की तरह अधिक ध्वनि करता है जो वस्तुओं (इकाइयों), फ़ंक्शन (इकाइयों), संपूर्ण पुस्तकालयों (इकाइयों) का परीक्षण कर सकता है, लेकिन कक्षा में स्थिर (इकाइयों के साथ) कुछ भी विफल हो सकता है।
v010dya

2
आप वैसे भी सभी बाहरी संदर्भों का मजाक नहीं मान रहे हैं? यदि आप हैं, तो सिंगलटन को मॉक करने में क्या समस्या है, यदि नहीं, तो क्या आप वास्तव में यूनिट टेस्टिंग कर रहे हैं?
Dainius

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

पावरमॉक स्थैतिक सामान का मजाक उड़ा सकता है।
Snicolas

किसी वस्तु का मज़ाक उड़ाने का मतलब असली वस्तु बनाना है? यदि मॉकिंग एक वास्तविक वस्तु नहीं बनाता है, तो इससे कोई फर्क नहीं पड़ता कि वर्ग सिंगलटन है या विधि स्टैटिक है?
अरुण राज

45

जब क्लस्टरिंग की बात आती है तो सिंग्लेटन्स भी खराब होते हैं । क्योंकि तब, आपके पास अब आपके आवेदन में "बिल्कुल एक सिंगलटन" नहीं है।

निम्नलिखित स्थिति पर विचार करें: एक डेवलपर के रूप में, आपको एक वेब एप्लिकेशन बनाना होगा जो एक डेटाबेस तक पहुंचता है। यह सुनिश्चित करने के लिए कि समवर्ती डेटाबेस कॉल एक दूसरे से संघर्ष नहीं करते हैं, आप एक थ्रेड-सेव बनाते हैं SingletonDao:

public class SingletonDao {
    // songleton's static variable and getInstance() method etc. omitted
    public void writeXYZ(...){
        synchronized(...){
            // some database writing operations...
        }
    }
}

तो आपको यकीन है कि आपके आवेदन में केवल एक सिंगलटन मौजूद है और सभी डेटाबेस केवल और केवल इसी के माध्यम से जाते हैं SingletonDao। आपका उत्पादन वातावरण अब इस तरह दिखता है: सिंगल सिंगलटन

सब कुछ अब तक ठीक है।

अब, विचार करें कि आप अपने वेब एप्लिकेशन के कई उदाहरणों को एक क्लस्टर में सेट करना चाहते हैं। अब, आपके पास अचानक कुछ ऐसा है:

कई सिंगलेट्स

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

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


4
यदि आप नहीं जानते कि सिंगलटन को कैसे लागू किया जाए, तो आपको ऐसा नहीं करना चाहिए। यदि आप नहीं जानते कि आप क्या कर रहे हैं, तो आपको पहले यह पता लगाना चाहिए, और उसके बाद केवल वही करना चाहिए जो आपको चाहिए।
Dainius

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

39
  1. यह आसानी से (एब) एक वैश्विक चर के रूप में उपयोग किया जाता है।
  2. एकल पर निर्भर करने वाले वर्ग एकल में इकाई परीक्षण के लिए अपेक्षाकृत कठिन हैं।

33

एकाधिकार शैतान और एकल-गैर-पठनीय / पारस्परिक स्थिति के साथ एकल हैं जो 'वास्तविक' समस्या हैं ...

सिंगलेट्स पढ़ने के बाद पैथोलॉजिकल लियर्स होते हैं जैसा कि जैसन के जवाब में सुझाया गया था, मैं इस छोटे से टीबिट में आया था जो यह बताता है कि सिंगल्सटन का अक्सर दुरुपयोग कैसे किया जाता है।

वैश्विक खराब है क्योंकि:

  • ए। यह नामस्थान संघर्ष का कारण बनता है
  • ख। यह अपरिवर्तित तरीके से राज्य को उजागर करता है

जब बात सिंगलेट्स की हो

  • ए। उन्हें फोन करने का स्पष्ट OO तरीका, टकराव को रोकता है, इसलिए बिंदु a। यह कोई मुद्दा नहीं है
  • ख। राज्य के बिना एकल (जैसे कारखाने) कोई समस्या नहीं है। राज्य के साथ सिंगलेट्स फिर से दो श्रेणियों में गिर सकते हैं, जो अपरिवर्तनीय हैं या एक बार लिखते हैं और कई (कॉन्फ़िगरेशन / संपत्ति फ़ाइलें) पढ़ते हैं। ये बुरे नहीं हैं। Mutable Singletons, जो एक तरह के रेफरेंस होल्डर होते हैं, जिनके बारे में आप बोल रहे होते हैं।

आखिरी बयान में वह ब्लॉग के 'सिंगलटन झूठे हैं' की अवधारणा का जिक्र कर रहे हैं।

यह एकाधिकार पर कैसे लागू होता है?

एकाधिकार का खेल शुरू करने के लिए, पहले:

  • हम पहले नियमों को स्थापित करते हैं इसलिए हर कोई एक ही पृष्ठ पर है
  • खेल की शुरुआत में सभी को एक समान शुरुआत दी जाती है
  • भ्रम से बचने के लिए नियमों का केवल एक सेट प्रस्तुत किया गया है
  • नियमों को पूरे खेल में बदलने की अनुमति नहीं है

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

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

अब खेल दोस्ताना पासा-रोलिंग से गंभीर व्यवसाय तक जाता है। बॉब को असफलता का उदाहरण बनाया गया है और जो और एड 'उस आदमी ’की तरह खत्म नहीं होना चाहते हैं। तो, आप प्रमुख खिलाड़ी होने के नाते, अचानक, दुश्मन बन जाते हैं। जो और एड एक-से-एक टेबल ट्रेडों, पीछे-पीछे मनी इंजेक्शन, अंडरवैलिड हाउस-स्वैपिंग का अभ्यास करना शुरू करते हैं और आम तौर पर एक खिलाड़ी के रूप में आपको कमजोर करने के लिए कुछ भी करते हैं जब तक कि उनमें से एक ऊपर तक नहीं पहुंच जाता।

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

इसलिए, यदि किसी गेम के लिए एक नियमपुस्तिका एक सिंगलटन का सटीक रूप से प्रतिनिधित्व करती है, तो एकाधिकार नियमपुस्तिका दुरुपयोग का एक उदाहरण होगी।

यह प्रोग्रामिंग पर कैसे लागू होता है?

सभी के बीच स्पष्ट थ्रेड-सेफ्टी और सिंक्रोनाइजेशन के मुद्दों के अलावा, जो परस्पर एकल मौजूद हैं ... यदि आपके पास डेटा का एक सेट है, जो कि कई अलग-अलग स्रोतों द्वारा समवर्ती रूप से पढ़ा / हेरफेर करने में सक्षम है और आवेदन निष्पादन के जीवनकाल के दौरान मौजूद है, यह संभवत: वापस कदम रखने और "मैं यहाँ डेटा संरचना के सही प्रकार का उपयोग कर रहा हूँ" पूछने का एक अच्छा समय है।

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

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


1
क्या होगा अगर सिंगलटन कुछ डेटा को कैश करता है?
योला

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

@ EvanPlaice: यहां तक ​​कि एक नकली के साथ, आपके पास कोड के साथ कुछ मुद्दे होंगे जो कहते हैं Singleton.getInstance()। एक भाषा जो प्रतिबिंब का समर्थन करती है, वह उस क्षेत्र में काम करने में सक्षम हो सकती है जहां एक सच्चा उदाहरण संग्रहीत है। IMO, हालाँकि, एक बार क्लास के निजी राज्य के साथ घूमने जाने के लिए टेस्ट थोड़ा कम भरोसेमंद हो जाते हैं।
cHao

28

सिंगलटन एकल उदाहरण के बारे में नहीं है!

अन्य उत्तरों के विपरीत, मैं इस बारे में बात नहीं करना चाहता कि सिंग्लेटों के साथ क्या गलत है, लेकिन आपको यह दिखाने के लिए कि सही इस्तेमाल होने पर वे कितने शक्तिशाली और भयानक हैं!

  • समस्या : सिंगलटन बहु-थ्रेडिंग वातावरण में एक चुनौती हो सकती है
    समाधान : अपने सिंगलटन की सभी निर्भरता को आरंभीकृत करने के लिए एकल थ्रेडेड बूटस्ट्रैप प्रक्रिया का उपयोग करें।
  • समस्या : एकल गायकों का मजाक उड़ाना कठिन है।
    समाधान : मॉकिंग के लिए विधि फैक्टरी पैटर्न का उपयोग करें

आप मैप कर सकते हैं MyModelकरने के लिए TestMyModelवर्ग है कि यह इनहेरिट करती है, हर जगह जब MyModelइंजेक्ट किया जाएगा आप मिल जाएगा TestMyModelinstread। - समस्या : सिंग्लेटन्स मेमोरी लीक का कारण बन सकते हैं क्योंकि उन्होंने कभी भी निस्तारण नहीं किया।
समाधान : खैर, उन्हें निपटान! अपने ऐप में एक कॉलबैक को ठीक से लागू करने के लिए कॉलबैक लागू करें, आपको उनसे जुड़े किसी भी डेटा को हटा देना चाहिए और अंत में: उन्हें फ़ैक्टरी से हटा दें।

जैसा कि मैंने कहा था कि सिंगलटन एकल उदाहरण के बारे में नहीं हैं।

  • सिंगलेट्स पठनीयता में सुधार करते हैं : आप अपनी कक्षा को देख सकते हैं और देख सकते हैं कि किस सिंग्लटन ने यह पता लगाने के लिए इंजेक्शन लगाया कि यह क्या निर्भरता है।
  • सिंग्लेटन्स रखरखाव में सुधार करता है : एक बार जब आप एक वर्ग से एक निर्भरता हटा देते हैं तो आपने कुछ सिंगलटन इंजेक्शन हटा दिए हैं, आपको अन्य वर्गों की एक बड़ी कड़ी को संपादित करने और संपादित करने की आवश्यकता नहीं है, जो आपके आस-पास की निर्भरता को स्थानांतरित कर देता है (यह मेरे लिए स्माइली कोड है @Jim बर्गर )
  • सिंगलेट्स स्मृति और प्रदर्शन में सुधार करते हैं : जब आपके आवेदन में कुछ बात होती है, और इसे डिलीवर करने के लिए कॉलबैक की एक लंबी श्रृंखला होती है, तो आप मेमोरी और प्रदर्शन को बर्बाद कर रहे हैं, सिंगलटन का उपयोग करके आप बीच के आदमी को काट रहे हैं, और अपने प्रदर्शन और मेमोरी के उपयोग में सुधार करें ( अनावश्यक स्थानीय चर आवंटन से बचकर)।

2
यह सिंगलेट्स के साथ मेरे मुख्य मुद्दे को संबोधित नहीं करता है जो कि वे आपकी परियोजना में हजारों वर्गों में से किसी से वैश्विक स्थिति तक पहुंच की अनुमति देते हैं।
लीजेंडल्रिक्सल

8
यही मकसद होगा ...
इल्या गज़मैन

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

23

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

मेरे द्वारा देखे गए दो सबसे बड़े स्क्रू अप्स हैं: इसे ग्लोबल की तरह मानना ​​और सिंगलटन क्लोजर को परिभाषित करने में असफल होना।

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

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

अन्य, कम आम, गलती सिंगलटन जीवनशैली की उपेक्षा करना है। सिर्फ इसलिए कि कोई मतलब नहीं है कि एक सिंगलटन कुछ सर्वशक्तिमान है "हमेशा था और हमेशा रहेगा", और न ही यह आमतौर पर वांछनीय है (एक शुरुआत और अंत के बिना ऑब्जेक्ट कोड में सभी प्रकार की उपयोगी मान्यताओं का उल्लंघन करते हैं, और केवल नियोजित होना चाहिए परिस्थितियों के सबसे हताश में।

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

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


23

विकिपीडिया सिंगलटन_पट्टन देखें

यह कुछ लोगों द्वारा एक विरोधी पैटर्न भी माना जाता है, जो महसूस करते हैं कि इसका अत्यधिक उपयोग किया जाता है, उन परिस्थितियों में अनावश्यक सीमाओं का परिचय देता है जहां एक वर्ग का एकमात्र उदाहरण वास्तव में आवश्यक नहीं है। [१] [२] [३] [४]

संदर्भ (लेख से केवल प्रासंगिक संदर्भ)

  1. ^ एलेक्स मिलर। पैटर्न I से नफरत है # 1: सिंगलटन , जुलाई 2007
  2. ^ स्कॉट डेंसमोर। क्यों विलक्षण हैं बुराई , मई 2004
  3. ^ स्टीव येजे। सिंगलटन को बेवकूफ माना जाता है , सितंबर 2004
  4. ^ जेबी रेंसबर्गर, आईबीएम। जुलाई 2001 को अपने सिंगलेट्स का बुद्धिमानी से उपयोग करें

8
पैटर्न के बारे में विवरण यह नहीं बताता है कि इसे बुराई क्यों माना जाता है ...
Jrgns

2
शायद ही उचित: "यह कुछ लोगों द्वारा एक विरोधी पैटर्न भी माना जाता है, जो महसूस करते हैं कि यह अत्यधिक उपयोग किया जाता है, उन परिस्थितियों में अनावश्यक सीमाओं का परिचय देता है जहां एक वर्ग का एकमात्र उदाहरण वास्तव में आवश्यक नहीं है।" संदर्भ देखें ... वैसे भी मेरे लिए RTFM है।
जीयूआई जंकाई

17

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

जब तक आप कोड में निम्नलिखित साधनों को लागू नहीं करते हैं तब तक एक वर्ग के एकल उदाहरण का उपयोग करना एक वैध निर्माण है:

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

  2. सुनिश्चित करें कि सिंगलटन थ्रेड-सुरक्षित है। वह दे दिया गया।

  3. सिंगलटन को सरल होना चाहिए और अत्यधिक जटिल नहीं होना चाहिए।

  4. आपके आवेदन के रनटाइम के दौरान, जहां सिंगलटन को किसी दिए गए ऑब्जेक्ट को पास करने की आवश्यकता होती है, एक क्लास फैक्ट्री का उपयोग करें जो उस ऑब्जेक्ट का निर्माण करती है और क्लास फैक्ट्री उस सिंगलटन इंस्टेंस को उस क्लास में पास करती है जिसे उसकी आवश्यकता होती है।

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

हमने अपने समाधानों में सिंगलेट्स का उपयोग बड़ी सफलता के साथ किया है जो समानांतर परीक्षण रन धाराओं में परीक्षण योग्य निर्धारक व्यवहार सुनिश्चित करते हैं।


+1, अंत में एक जवाब है कि पतों जब एक सिंगलटन मान्य हो सकता है।
पचेरियर

16

मैं स्वीकृत उत्तर में 4 बिंदुओं को संबोधित करना चाहता हूं, उम्मीद है कि कोई मुझे समझा सकता है कि मैं गलत क्यों हूं।

  1. आपके कोड में निर्भरता क्यों खराब है? पहले से ही दर्जनों छिपी हुई निर्भरताएं हैं (सी रनटाइम कॉल, ओएस एपीआई कॉल, वैश्विक फ़ंक्शन कॉल), और सिंगलटन निर्भरताएं खोजना आसान है (उदाहरण के लिए खोज) ()।

    "इसके चारों ओर से गुजरने से बचने के लिए कुछ वैश्विक बनाना एक कोड गंध है।" क्यों यह एक सिंगलटन एक कोड गंध बनाने से बचने के लिए कुछ पास नहीं है?

    यदि आप किसी कॉल स्टैक में केवल 10 कार्यों के माध्यम से एक ऑब्जेक्ट पास कर रहे हैं, तो एक सिंगलटन से बचने के लिए, क्या यह इतना बढ़िया है?

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

  3. किसी कक्षा में किसी वस्तु को पास करने से वह कक्षा के भीतर से एकल के रूप में उस वस्तु का उपयोग करने की तुलना में अधिक कड़ा हो जाता है?

  4. यह क्यों बदलता है कि राज्य कितने समय तक रहता है? सिंगलटन मैन्युअल रूप से बनाए या नष्ट किए जा सकते हैं, इसलिए नियंत्रण अभी भी है, और आप जीवनकाल को एक सिंगल-सिंगलटन ऑब्जेक्ट के जीवनकाल के समान बना सकते हैं।

इकाई परीक्षणों के बारे में:

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

1
1. वे सभी छिपी हुई निर्भरताएँ? वो भी खराब हैं। छिपी हुई निर्भरता हमेशा बुराई होती है। लेकिन CRT और OS के मामले में, वे पहले से ही वहां हैं, और वे कुछ करने का एकमात्र तरीका हैं। (रनटाइम या ओएस का उपयोग किए बिना एक सी प्रोग्राम लिखने की कोशिश करें।) यह करने की क्षमता काफी हद तक उनकी नकारात्मकता को दूर करती है। हमारे कोड में सिंगलटन को वह विलासिता नहीं मिलती है; चूंकि वे हमारे नियंत्रण और जिम्मेदारी के क्षेत्र में दृढ़ता से हैं, हर उपयोग (पढ़ें: प्रत्येक अतिरिक्त छिपी निर्भरता) सामान प्राप्त करने का एकमात्र उचित तरीका के रूप में उचित होना चाहिए। बहुत, उनमें से बहुत कम वास्तव में हैं।
cHao

2. "जिम्मेदारी" को आमतौर पर "परिवर्तन का कारण" के रूप में परिभाषित किया गया है। एक सिंगलटन अपने जीवनकाल का प्रबंधन और अपनी वास्तविक नौकरी करने दोनों को समाप्त करता है। यदि आप बदलते हैं कि नौकरी कैसे की जाती है या ऑब्जेक्ट ग्राफ कैसे बनाया जाता है, तो आपको कक्षा को बदलना होगा। लेकिन अगर आपके पास अन्य कोड ऑब्जेक्ट ग्राफ का निर्माण करता है, और आपकी कक्षा सिर्फ अपना असली काम करती है, तो आरंभिक कोड ऑब्जेक्ट का ग्राफ़ सेट कर सकता है, जो आपको पसंद है। सब कुछ बहुत अधिक मॉड्यूलर और परीक्षण योग्य है, क्योंकि आप टेस्ट डबल्स सम्मिलित कर सकते हैं और अपनी इच्छा के अनुसार सब कुछ फाड़ सकते हैं, और आप अब छिपे हुए हिस्सों पर भरोसा नहीं कर सकते हैं।
cHao

1
@ का-हाओ: 1. यह अच्छा है कि आप यह पहचानें कि "सामानों को करने की क्षमता उनकी नकारात्मकताओं को दूर करती है।" एक उदाहरण एक लॉगिंग ढांचा होगा। डेवलपर्स कॉलिंग से हतोत्साहित होने का मतलब है कि फ़ंक्शन कॉल की परतों के माध्यम से निर्भरता इंजेक्शन द्वारा एक वैश्विक लॉगिंग ऑब्जेक्ट को पास करना अनिवार्य है। इसलिए, सिंगलटन। 3. आपका तंग युग्मन बिंदु केवल प्रासंगिक है यदि आप वर्ग के ग्राहकों को बहुरूपता के माध्यम से व्यवहार को नियंत्रित करना चाहते हैं। अक्सर ऐसा नहीं होता।
जॉन

2
4. मुझे यकीन नहीं है कि "मैन्युअल रूप से नष्ट नहीं किया जा सकता है" "केवल एक उदाहरण हो सकता है" का एक तार्किक निहितार्थ है। यदि आप एकल को परिभाषित करते हैं, तो हम उसी चीज़ के बारे में बात नहीं कर रहे हैं। सभी वर्गों को इकाई परीक्षण नहीं किया जाना चाहिए । यह एक व्यावसायिक निर्णय है, और कभी-कभी समय-समय पर बाजार या विकास लागत पूर्वता ले जाएगा।
जॉन

1
3. यदि आप बहुरूपता नहीं चाहते हैं, तो आपको एक उदाहरण की भी आवश्यकता नहीं है। आप इसे एक स्थिर वर्ग भी बना सकते हैं, क्योंकि आप अपने आप को एक ही वस्तु और एक ही कार्यान्वयन के लिए वैसे भी बांध रहे हैं - और कम से कम तब एपीआई आपके लिए उतना झूठ नहीं बोलता।
cHao

15

विंस हस्टन के पास ये मापदंड हैं, जो मुझे उचित लगते हैं:

सिंगलटन को केवल तभी माना जाना चाहिए जब निम्नलिखित तीन मानदंड संतुष्ट हों:

  • एकल उदाहरण का स्वामित्व यथोचित असाइन नहीं किया जा सकता है
  • आलसी आरंभीकरण वांछनीय है
  • अन्यथा के लिए वैश्विक पहुंच प्रदान नहीं की गई है

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


14

एकल बिंदु की शुद्धता से बुरे हैं।

एक व्यावहारिक दृष्टिकोण से, एक सिंगलटन एक व्यापार-बंद विकासशील समय बनाम जटिलता है

यदि आप जानते हैं कि आपके आवेदन में बदलाव नहीं होगा, तो वे साथ जाने के लिए बहुत ठीक हैं। बस यह जान लें कि अगर आपकी आवश्यकताओं में अप्रत्याशित तरीके से बदलाव होता है (जो कि ज्यादातर मामलों में बहुत ठीक है) तो आपको चीजों को फिर से तैयार करना पड़ सकता है।

सिंगलेट्स कभी-कभी इकाई परीक्षण को भी जटिल करते हैं ।


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

1
AFAIK सिंगलटन है एक कारखाने विधि। इस प्रकार मुझे आपकी सिफारिश नहीं मिली।
tacone

3
"A factory"! = "A factory_method जिसे उसी कक्षा में अन्य उपयोगी सामान से अलग नहीं किया जा सकता है"
स्वेन

13

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

मेरा मानना ​​है कि बैकलैश इसके अति प्रयोग के कारण है, जो इस तथ्य के कारण है कि यह समझने और लागू करने का सबसे आसान पैटर्न है।


6
मुझे लगता है कि बैकलैश को औपचारिक इकाई परीक्षण का अभ्यास करने वाले लोगों के साथ यह महसूस करने के लिए अधिक है कि वे इससे निपटने के लिए एक बुरा सपना हैं।
जिम बर्गर

1
यकीन नहीं होता कि यह -1 क्यों है। यह सबसे वर्णनात्मक उत्तर नहीं है, लेकिन वह गलत भी नहीं है।
डाकू प्रोग्रामर

13

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


3
डिफ़ॉल्ट रूप से, सिंगलेट्स द्वारा स्प्रिंग बीन्स नहीं हैं?
स्लिम

3
हाँ, लेकिन मेरा मतलब है 'सिंगल' कोडिंग। मैंने 'एक सिंगलटन' नहीं लिखा है (अर्थात एक निजी निर्माणकर्ता यादा यादा यादा प्रतिरूप के अनुसार) - लेकिन हां, वसंत के साथ मैं एक उदाहरण का उपयोग कर रहा हूं।
19

4
इसलिए जब अन्य लोग ऐसा करते हैं, तो यह ठीक है (यदि मैं उसके बाद का उपयोग करूंगा), लेकिन यदि अन्य इसे करते हैं और मैं इसका उपयोग नहीं करूंगा, तो यह बुराई है।
Dainius

11

सिंगलटन एक पैटर्न है और किसी भी अन्य टूल की तरह इसका उपयोग या दुरुपयोग किया जा सकता है।

एक सिंगलटन का बुरा हिस्सा आम तौर पर उपयोगकर्ता है (या मुझे उन चीजों के लिए एक सिंगलटन के अनुचित उपयोग को कहना चाहिए जो इसे करने के लिए डिज़ाइन नहीं किया गया है)। सबसे बड़ा अपराधी एक सिंगलटन का उपयोग नकली वैश्विक चर के रूप में कर रहा है।


1
धन्यवाद लोकी :) बिल्कुल मेरी बात। पूरी चुड़ैल का शिकार मुझे गोटो डिबेट की याद दिलाता है। उपकरण उन लोगों के लिए हैं जो जानते हैं कि उनका उपयोग कैसे करना है; एक उपकरण का उपयोग करना जिसे आप पसंद नहीं करते हैं वह आपके लिए खतरनाक हो सकता है इसलिए इसे टालें लेकिन दूसरों को यह बताने के लिए उपयोग न करें कि इसे ठीक से उपयोग न करना सीखें। मैं बिल्कुल "प्रो-सिंगलटन" नहीं हूं, लेकिन मुझे इस तथ्य की तरह है कि मेरे पास ऐसा उपकरण है और मैं महसूस कर सकता हूं कि इसका उपयोग करना कहां तक ​​उचित है। अवधि।
dkellner 16

8

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

एकल से नियमित वस्तुओं तक ले जाने के लिए उन्हें बहुत मुश्किल होता है।

इसके अलावा, एक गैर-थ्रेड-सुरक्षित सिंगलटन लिखना बहुत आसान है।

सिंगलेट्स का उपयोग करने के बजाय, आपको फ़ंक्शन से फ़ंक्शन तक सभी आवश्यक उपयोगिता ऑब्जेक्ट पास करना चाहिए। यह आसान हो सकता है यदि आप उन सभी को एक सहायक वस्तु में लपेटते हैं, जैसे:

void some_class::some_function(parameters, service_provider& srv)
{
    srv.get<error_logger>().log("Hi there!");
    this->another_function(some_other_parameters, srv);
}

4
हर विधि के लिए तर्क वितर्क करना शानदार है, यह कम से कम शीर्ष 10 तरीकों पर जाना चाहिए कि कैसे अपने एपीआई को प्रदूषित करें।
Dainius

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

निर्भर करता है कि आप क्या परीक्षण कर रहे हैं, यदि आप सिंगलटन का परीक्षण नहीं कर रहे हैं, तो आपको परवाह है कि यह कैसे व्यवहार करता है, यदि आपकी 2 दूरस्थ वस्तु एक दूसरे के व्यवहार पर निर्भर करती है, तो यह सिंगलटन समस्या नहीं है ..
Dainius

क्या आप नेस्टेड कॉल में कौन सी भाषा का प्रचार करेंगे?
Dainius

1
यदि आपके पास एक मॉड्यूल है जो दूसरे पर निर्भर करता है और आप इसे नहीं जानते / नहीं कर सकते हैं, तो आपके पास कठोर अनियमितता होगी कि यह सिंगलटन है या नहीं। लोग अक्सर विरासत के तरीके का उपयोग कर रहे हैं, जहां उन्हें रचना का उपयोग करना चाहिए, लेकिन आप यह नहीं कहते हैं कि विरासत खराब है, और OOP को हर कीमत पर बचना चाहिए, क्योंकि इतने सारे लोग वहां डिजाइन गलतियां कर रहे हैं, या आप हैं?
Dainius

8

एकल के साथ समस्याएं बढ़ी हुई गुंजाइश और इसलिए युग्मन का मुद्दा है । इस बात से इनकार नहीं किया जा सकता है कि कुछ स्थितियाँ ऐसी हैं जहाँ आपको एक ही उदाहरण तक पहुँच की आवश्यकता होती है, और इसे अन्य तरीकों से पूरा किया जा सकता है।

अब मैं नियंत्रण (IoC) कंटेनर के एक व्युत्क्रम के आसपास डिजाइन करना पसंद करता हूं और जीवनकाल को कंटेनर द्वारा नियंत्रित करने की अनुमति देता हूं । यह आपको उन वर्गों का लाभ देता है जो इस तथ्य से अनभिज्ञ हैं कि इस तथ्य से अनजान हैं कि एकल उदाहरण है। भविष्य में सिंगलटन के जीवनकाल को बदला जा सकता है। एक बार इस तरह के उदाहरण के बाद मुझे हाल ही में सिंगल थ्रेड से मल्टी थ्रेडेड में एक आसान समायोजन मिला।

एफडब्ल्यूआईडब्ल्यू, यदि यह एक पीआईए है जब आप इसे इकाई परीक्षण की कोशिश करते हैं तो यह पीआईए में जा रहा है जब आप डीबग करने, बग ठीक करने या इसे बढ़ाने की कोशिश करते हैं।


8

इस विषय पर हाल ही में लेख बिना किसी टिप्पणी के कोडिंग पर क्रिस रीथ द्वारा ।

नोट: टिप्पणियों के बिना कोडिंग अब मान्य नहीं है। हालाँकि, लेख को किसी अन्य उपयोगकर्ता द्वारा क्लोन किया गया है।

http://geekswithblogs.net/AngelEyes/archive/2013/09/08/singleton-i-love-you-but-youre-bringing-me-down-re-uploaded.aspx


7

सिंगलनेट खराब नहीं हैं। यह केवल तभी बुरा है जब आप विश्व स्तर पर कुछ अनोखा बनाते हैं जो विश्व स्तर पर अद्वितीय नहीं है।

हालांकि, "एप्लिकेशन स्कोप सर्विसेज" हैं (एक मैसेजिंग सिस्टम के बारे में सोचें जो घटकों को इंटरैक्ट करता है) - यह एक सिंगलटन के लिए कॉल करता है, एक "मैसेजक्यूएयू" - क्लास जिसमें एक विधि "SendMessage (...)" है।

फिर आप सभी जगह से निम्न कार्य कर सकते हैं:

MessageQueue.Current.SendMessage (नया MailArrivedMessage (...));

और, ज़ाहिर है, करो:

MessageQueue.Current.RegisterReceiver (this);

IMessageReceiver को लागू करने वाली कक्षाओं में।


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

1
इसके अलावा, हमारे पास सिर्फ एक वैश्विक CustomerOrLList क्यों नहीं होना चाहिए, ताकि हम इसे MessageQueue की तरह कहीं से भी अच्छी तरह से कॉल कर सकें? मेरा मानना ​​है कि उत्तर दोनों के लिए समान है: यह प्रभावी रूप से एक वैश्विक चर बना रहा है।
लेजेंडल्रिक्सल

7

बहुत से लोग वस्तुओं को डालते हैं जो एक सिंगलटन पैटर्न में सुरक्षित नहीं होते हैं। मैंने एक डेटा पैटर्न में एक DataContext ( LINQ to SQL ) के उदाहरण देखे हैं , इस तथ्य के बावजूद कि DataContext थ्रेड सुरक्षित नहीं है और विशुद्ध रूप से एक यूनिट-ऑफ-वर्क ऑब्जेक्ट है।


कई लोग असुरक्षित मल्टी-थ्रेडेड कोड लिखते हैं, क्या इसका मतलब है कि हमें थ्रेड्स को खत्म करना चाहिए?
Dainius

@ डाइनियस: वास्तव में, हाँ। IMO डिफ़ॉल्ट कॉन्सेप्ट मॉडल बहु-प्रक्रिया होना चाहिए, दो प्रक्रियाओं के लिए एक तरह से (1) एक दूसरे को आसानी से संदेश भेजते हैं, और / या (2) एक आवश्यक आधार पर स्मृति साझा करते हैं। थ्रेडिंग उपयोगी है यदि आप सब कुछ साझा करना चाहते हैं , लेकिन आप वास्तव में ऐसा कभी नहीं चाहते हैं। पूरे पते के स्थान को साझा करके इसका अनुकरण किया जा सकता है, लेकिन इसे एक विरोधी पैटर्न भी माना जाएगा।
cHao

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

इसलिए यदि आपके पास डेटा का विशाल मैट्रिक्स है, जिसे आपको प्रक्रिया की आवश्यकता है, तो इसे एक ही धागे में करना बेहतर है, क्योंकि बहुत से लोग ऐसा गलत कर सकते हैं ..
Dainius

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

6

यहाँ एक और बात एकल गीतों के बारे में है जो अभी तक किसी ने नहीं कहा।

ज्यादातर मामलों में "एकलता" अपने इंटरफ़ेस की विशेषता के बजाय कुछ वर्ग के लिए कार्यान्वयन का एक विवरण है। नियंत्रण कंटेनर का उलटा वर्ग उपयोगकर्ताओं से इस विशेषता को छिपा सकता है; आपको बस अपनी कक्षा को एक सिंगलटन के रूप में चिह्नित करना होगा ( @Singletonउदाहरण के लिए जावा में एनोटेशन के साथ ) और यही है; आईओसीसी बाकी काम करेगी। आपको अपने सिंगलटन उदाहरण के लिए वैश्विक पहुंच प्रदान करने की आवश्यकता नहीं है क्योंकि एक्सेस पहले से ही IoCC द्वारा प्रबंधित है। इस प्रकार आईओसी सिंगलेट्स के साथ कुछ भी गलत नहीं है।

IoC सिंगलेट्स के विपरीत GoF सिंगललेट्स को getInstance () विधि के माध्यम से इंटरफ़ेस में "सिंगलटनिटी" को उजागर करना है, और ताकि वे ऊपर बताई गई सभी चीजों से पीड़ित हों।


3
मेरी राय में, "एकलता" एक रन-टाइम पर्यावरण विवरण है, और उस प्रोग्रामर द्वारा विचार नहीं किया जाना चाहिए जिसने क्लास कोड लिखा था। बल्कि, यह USER वर्ग द्वारा बनाया जाने वाला एक विचार है। केवल USER जानता है कि वास्तव में कितने उदाहरणों की आवश्यकता है।
पृथ्वी इंजन

5

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


बहुत बढ़िया! पूरी तरह से सहमत हूँ! लेकिन आप कर सकते हैं, और शायद, अधिक विस्तृत होना चाहिए। इस तरह के विस्तार के रूप में जो डिजाइन पैटर्न सबसे अधिक नजरअंदाज कर रहे हैं और कैसे "ठीक से और कम से कम" एकल का उपयोग करें। आसान से कहा किया ! : पी
क्रैगॉक्स

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

5

सबसे पहले एक वर्ग और उसके सहयोगियों को सबसे पहले आश्रितों पर ध्यान केंद्रित करने के बजाय अपने इच्छित उद्देश्य को पूरा करना चाहिए। जीवनचक्र प्रबंधन (जब उदाहरण बनाए जाते हैं और जब वे दायरे से बाहर हो जाते हैं) कक्षाओं की जिम्मेदारी का हिस्सा नहीं होना चाहिए। इसके लिए स्वीकृत सर्वोत्तम अभ्यास निर्भरता इंजेक्शन का उपयोग कर निर्भरता को प्रबंधित करने के लिए एक नए घटक को शिल्प या कॉन्फ़िगर करना है।

अक्सर सॉफ्टवेयर अधिक जटिल हो जाता है यह समझ में आता है कि विभिन्न राज्य के साथ सिंगलटन वर्ग के कई स्वतंत्र उदाहरण हैं। केवल सिंगलटन को हथियाने के लिए कमिटिंग कोड ऐसे मामलों में गलत है। Singleton.getInstance()छोटे सरल सिस्टम के लिए उपयोग करना ठीक हो सकता है, लेकिन जब यह एक ही वर्ग के विभिन्न उदाहरण की आवश्यकता हो सकती है, तो यह काम नहीं करता है।

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

परीक्षण में सिंगलटन के कारण होने वाली समस्याएं उनकी हार्ड कोडित एकल उपयोग मामले / पर्यावरण का एक लक्षण है। परीक्षण सूट और कई परीक्षण प्रत्येक व्यक्ति हैं और कुछ को अलग करते हैं जो एक सिंगलटन कोडिंग के साथ संगत नहीं है।


4

क्योंकि वे मूल रूप से वैश्विक उन्मुख वस्तु हैं, आप आमतौर पर अपनी कक्षाओं को इस तरह से डिजाइन कर सकते हैं ताकि आपको उनकी आवश्यकता न हो।


यदि आप कक्षा एक बार उदाहरण के लिए सीमित नहीं हैं, तो आपको अपनी कक्षा में स्थिर सदस्यों की ज़रूरत होगी जो सेमफोर द्वारा प्रबंधित किए जाते हैं जो कि बहुत ही समान हैं! आपका प्रस्तावित विकल्प क्या है?
जाइच

मेरे पास "मेनस्क्रीन" के साथ एक विशाल एप्लिकेशन है यह स्क्रीन कई छोटे मोडल / नॉन मोडल विंडो / यूआई फॉर्म खोलती है। IMHO मुझे लगता है कि मेनस्क्रीन एक सिंगलटन होना चाहिए ताकि उदाहरण के लिए, एप्लिकेशन के दूर कोने में एक विजेट कहीं न कहीं मेनस्क्रीन के स्टेटस बार में अपनी स्थिति दिखाना चाहता है, यह सब करना है MainScreen.getInstance ()। setStatus () "कुछ पाठ"); आप एक विकल्प के रूप में क्या प्रस्ताव करते हैं? आवेदन भर में MainScreen पास ?? : डी
साल्विन फ्रांसिस

2
@ सैल्विनफ्रांसिस: मैं जो सिफारिश करूंगा, आप उन वस्तुओं के बारे में ध्यान देना बंद कर दें जिनकी उन्हें परवाह नहीं करनी चाहिए और एक-दूसरे के साथ खिलवाड़ करने के लिए ऐप के पार नहीं जाना चाहिए। :) आपका उदाहरण घटनाओं के साथ बेहतर किया जाएगा। जब आप घटनाओं को सही ढंग से करते हैं, तो एक विजेट को यह भी ध्यान रखने की ज़रूरत नहीं है कि क्या कोई मेनस्क्रीन है; यह सिर्फ "हे, सामान हुआ" प्रसारित करता है, और जो कुछ भी "सामान हुआ" घटना के लिए सदस्यता लिया है (यह एक मेनस्क्रीन, एक विजेट, या कुछ और पूरी तरह से!) तय करता है कि वह कैसे जवाब देना चाहता है। वैसे भी OOP माना जाता है। :)
cHao

1
@ साल्विन पर विचार करें कि डिबगिंग के दौरान मेनस्क्रीन के बारे में कितना मुश्किल है अगर यह कई घटकों द्वारा 'चुपचाप' अपडेट किया जा रहा है। आपका उदाहरण एक सही कारण है कि सिंगललेट खराब क्यों हैं।
लीजेंडलॉग्रान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.