design patterns - सिंगलेट्स के बारे में इतना बुरा क्या है?




design-patterns singleton (20)

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

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

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


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

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

  • समस्या : बहु-थ्रेडिंग वातावरण में सिंगलटन एक चुनौती हो सकती है
    समाधान : अपने सिंगलटन की सभी निर्भरताओं को आरंभ करने के लिए एक थ्रेडेड बूटस्ट्रैप प्रक्रिया का उपयोग करें।
  • समस्या : सिंगलेट्स का मज़ाक करना मुश्किल है।
    समाधान : मॉकिंग के लिए विधि Factory पैटर्न का उपयोग करें
    MyModel myModel = Factory.inject(MyModel.class); आप MyModel को TestMyModel क्लास में मैप कर सकते हैं जो इसे विरासत में लेता है, हर जगह जब MyModel इंजेक्शन दिया जाएगा तो आपको TestMyModel instread मिलेगा।
  • समस्या : सिंगलेट्स मेमोरी लीक का कारण बन सकता है क्योंकि उन्होंने कभी निपटान नहीं किया था।
    समाधान : ठीक है, उनका निपटान करें! एक एपलेट्स को सही तरीके से निपटाने के लिए अपने ऐप में कॉलबैक लागू करें, आपको उनसे जुड़े किसी भी डेटा को हटा देना चाहिए और अंत में: उन्हें फैक्ट्री से हटा दें।

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

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

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

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


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

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

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

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

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

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

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

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


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

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

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

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

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


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

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


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

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

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

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

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

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

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


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

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

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

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


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

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

तो मूल रूप से:

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

बजाय:

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

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

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


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

इसे कुछ लोगों द्वारा एक विरोधी पैटर्न भी माना जाता है, जो महसूस करते हैं कि इसका अत्यधिक उपयोग किया जाता है, ऐसी परिस्थितियों में अनावश्यक सीमाएं पेश करते हैं जहां कक्षा का एकमात्र उदाहरण वास्तव में आवश्यक नहीं होता है। [1] [2] [3] [4]

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

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

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

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

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

  • ए। यह नामस्थान संघर्ष का कारण बनता है
  • ख। यह राज्य को एक अनचाहे फैशन में उजागर करता है

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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


Because they are basically object oriented global variables, you can usually design your classes in such a way so that you don't need them.


Firstly a class and its collaborators should firstly perform their intended purpose rather than focusing on deoendents. Lifecycle management (when instances are creared snd when they go out of scope) should not be part of the cladses responsibility. The accepted best practice for this is to craft or configure a new component to manage dependencies using dependency injection.

Often software gets more complicated it makes sense to have multiple independent instances of the "singleton" class with different state. Committing code to simply grab the singleton is wrong in such cases. Using Singleton.getInstance() might be ok for small simple systems but it doesn't work / scale when one might need a different instance of the same class.

No class should be thought of as a singleton but rather that should be an aplication of it's usage or how it is used to configure dependents. For a quick and nasty this does not matter- just luke hardcoding say file paths does not matter but for bigger applications such dependencies need to be factored out and managed in more appropriate way using DI.

The problems that singleton cause in testing is a symptom of their hard coded single usage case/environment. The test suite and the many tests are each individual and separate something that is not compatible with hardcoding a singleton.


I'm not going to comment on the good/evil argument, but I haven't used them since Spring came along. Using dependency injection has pretty much removed my requirements for singleton, servicelocators and factories. I find this a much more productive and clean environment, at least for the type of work I do (Java-based web applications).



Singletons are NOT bad. It's only bad when you make something globally unique that isn't globally unique.

However, there are "application scope services" (think about a messaging system that makes components interact) - this CALLS for a singleton, a "MessageQueue" - class that has a method "SendMessage(...)".

You can then do the following from all over the place:

MessageQueue.Current.SendMessage(new MailArrivedMessage(...));

And, of course, do:

MessageQueue.Current.RegisterReceiver(this);

in classes that implement IMessageReceiver.


Singletons are bad from a purist point of view.

From a pratical point of view, a singleton is a trade-off developing time vs complexity .

If you know your application won't change that much they are pretty OK to go with. Just know that you may need to refactor things up if your requirements change in an unexpected way (which is pretty OK in most cases).

Singletons sometimes also complicate unit testing .


There is nothing inherently wrong with the pattern, assuming it is being used for some aspect of your model which is truly single.

I believe the backlash is due to its overuse which, in turn, is due to the fact that it's the easiest pattern to understand and implement.


Too many people put objects which are not thread safe in a singleton pattern. I've seen examples of a DataContext ( LINQ to SQL ) done in a singleton pattern, despite the fact that the DataContext is not thread safe and is purely a unit-of-work object.





singleton