जावा में सिंगलटन क्या है?
सिंगलटन सबसे सरल वर्ग-स्तरीय डिज़ाइन पैटर्न में से एक है। कभी-कभी लोग कहते हैं "यह वर्ग सिंगलटन है", जिसका अर्थ है कि वर्ग सिंगलटन डिज़ाइन पैटर्न को लागू करता है। कभी-कभी एक वर्ग लिखना आवश्यक होता है जहाँ हम किसी एक वस्तु के लिए तात्कालिकता को प्रतिबंधित करते हैं। उदाहरण के लिए, लॉगिंग या किसी से जुड़ने के लिए जिम्मेदार वर्ग डेटाबेस। सिंगलटन डिज़ाइन पैटर्न बताता है कि हम इसे कैसे प्राप्त कर सकते हैं। सिंगलटन एक डिज़ाइन पैटर्न है जो दो काम करता है:-
यह गारंटी देता है कि कक्षा का केवल एक ही उदाहरण होगा।
-
यह उस उदाहरण के लिए वैश्विक पहुंच का एकल बिंदु प्रदान करता है।
-
एक निजी निर्माता। यह कक्षा के बाहर ही कक्षा की वस्तुओं को बनाने की क्षमता को सीमित करता है।
-
एक सार्वजनिक स्थैतिक विधि जो कक्षा का उदाहरण लौटाती है। इस विधि को getInstance कहा जाता है । यह वर्ग उदाहरण के लिए वैश्विक पहुँच का बिंदु है।
कार्यान्वयन के विकल्प
सिंगलटन डिज़ाइन पैटर्न को विभिन्न तरीकों से लागू किया जाता है। प्रत्येक विकल्प अपने तरीके से अच्छा और बुरा है। हमेशा की तरह, यहाँ कोई सटीक विकल्प नहीं है, लेकिन हमें एक के लिए प्रयास करना चाहिए। सबसे पहले, आइए तय करें कि क्या अच्छा और बुरा बनता है, और कौन से मेट्रिक्स प्रभावित करते हैं कि हम डिज़ाइन पैटर्न के विभिन्न कार्यान्वयनों का आकलन कैसे करते हैं। चलिए अच्छे से शुरू करते हैं। यहां ऐसे कारक हैं जो कार्यान्वयन को अधिक रसदार और आकर्षक बनाते हैं:-
आलसी आरंभीकरण: उदाहरण तब तक नहीं बनाया जाता जब तक इसकी आवश्यकता न हो।
-
सरल और पारदर्शी कोड: यह मीट्रिक, निश्चित रूप से व्यक्तिपरक है, लेकिन यह महत्वपूर्ण है।
-
थ्रेड सुरक्षा: बहु-थ्रेडेड वातावरण में सही संचालन।
-
बहु-थ्रेडेड वातावरण में उच्च प्रदर्शन: संसाधन साझा करते समय बहुत कम या कोई थ्रेड ब्लॉकिंग नहीं।
-
कोई आलसी प्रारंभिकरण नहीं: जब आवेदन शुरू होने पर कक्षा लोड हो जाती है, भले ही इसकी आवश्यकता हो या नहीं (विरोधाभासी रूप से, आईटी दुनिया में आलसी होना बेहतर है)
-
जटिल और पढ़ने में मुश्किल कोड। यह मीट्रिक भी व्यक्तिपरक है। अगर आपकी आंखों से खून बहना शुरू हो जाता है, तो हम मान लेंगे कि कार्यान्वयन सबसे अच्छा नहीं है।
-
थ्रेड सुरक्षा का अभाव। दूसरे शब्दों में, "थ्रेड डेंजर"। बहु-थ्रेडेड वातावरण में गलत संचालन।
-
बहु-थ्रेडेड वातावरण में खराब प्रदर्शन: संसाधन साझा करते समय थ्रेड्स एक-दूसरे को हर समय या अक्सर ब्लॉक करते हैं।
कोड
अब हम कार्यान्वयन के विभिन्न विकल्पों पर विचार करने के लिए तैयार हैं और पेशेवरों और विपक्षों को इंगित करते हैं:सरल
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
सबसे सरल कार्यान्वयन। पेशेवरों:
-
सरल और पारदर्शी कोड
-
थ्रेड सुरक्षा
-
बहु-थ्रेडेड वातावरण में उच्च प्रदर्शन
- कोई आलसी आरंभीकरण नहीं।
आलसी आरंभीकरण
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
पेशेवरों:
-
आलसी आरंभीकरण।
-
धागा सुरक्षित नहीं
सिंक्रोनाइज़्ड एक्सेस
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
पेशेवरों:
-
आलसी आरंभीकरण।
-
थ्रेड सुरक्षा
-
खराब मल्टीथ्रेडेड प्रदर्शन
डबल-चेक लॉकिंग
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
पेशेवरों:
-
आलसी आरंभीकरण।
-
थ्रेड सुरक्षा
-
बहु-थ्रेडेड वातावरण में उच्च प्रदर्शन
-
1.5 से नीचे जावा के पुराने संस्करणों में समर्थित नहीं है (अस्थिर कीवर्ड का उपयोग 1.5 संस्करण के बाद से तय है)
वर्ग धारक
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}
पेशेवरों:
-
आलसी आरंभीकरण।
-
थ्रेड सुरक्षा।
-
बहु-थ्रेडेड वातावरण में उच्च प्रदर्शन।
-
सही संचालन के लिए एक गारंटी की आवश्यकता होती है कि सिंगलटन ऑब्जेक्ट बिना किसी त्रुटि के प्रारंभ हो। अन्यथा, getInstance विधि के लिए पहली कॉल के परिणामस्वरूप ExceptionInInitializerError होगा, और बाद की सभी कॉल NoClassDefFoundError उत्पन्न करेंगी ।
कार्यान्वयन | आलसी आरंभीकरण | थ्रेड सुरक्षा | मल्टीथ्रेडेड प्रदर्शन | कब इस्तेमाल करें? |
---|---|---|---|---|
सरल | - | + | तेज़ | कभी नहीँ। या संभवतः जब आलसी आरंभीकरण महत्वपूर्ण नहीं है। लेकिन कभी बेहतर नहीं होता। |
आलसी आरंभीकरण | + | - | लागू नहीं | हमेशा जब मल्टीथ्रेडिंग की जरूरत नहीं होती है |
सिंक्रोनाइज़्ड एक्सेस | + | + | धीमा | कभी नहीँ। या संभवतः जब बहुप्रचारित प्रदर्शन कोई फर्क नहीं पड़ता। लेकिन कभी बेहतर नहीं होता। |
डबल-चेक लॉकिंग | + | + | तेज़ | दुर्लभ मामलों में जब आपको सिंगलटन बनाते समय अपवादों को संभालने की आवश्यकता होती है (जब क्लास होल्डर सिंगलटन लागू नहीं होता है) |
वर्ग धारक | + | + | तेज़ | जब भी मल्टीथ्रेडिंग की आवश्यकता होती है और इस बात की गारंटी होती है कि बिना किसी समस्या के सिंगलटन ऑब्जेक्ट बनाया जाएगा। |
सिंगलटन पैटर्न के पक्ष और विपक्ष
सामान्य तौर पर, एक सिंगलटन वही करता है जिसकी उससे अपेक्षा की जाती है:-
यह गारंटी देता है कि कक्षा का केवल एक ही उदाहरण होगा।
-
यह उस उदाहरण के लिए वैश्विक पहुंच का एकल बिंदु प्रदान करता है।
-
एक सिंगलटन एकल उत्तरदायित्व सिद्धांत का उल्लंघन करता है: अपने प्रत्यक्ष कर्तव्यों के अतिरिक्त, सिंगलटन वर्ग उदाहरणों की संख्या को भी नियंत्रित करता है।
-
एक सिंगलटन पर सामान्य वर्ग की निर्भरता वर्ग के सार्वजनिक अनुबंध में दिखाई नहीं दे रही है।
-
वैश्विक चर खराब हैं। अंततः, एक सिंगलटन एक विशाल वैश्विक चर में बदल जाता है।
-
एक सिंगलटन की उपस्थिति समग्र रूप से एप्लिकेशन की टेस्टेबिलिटी को कम कर देती है और विशेष रूप से सिंगलटन का उपयोग करने वाली कक्षाएं।
GO TO FULL VERSION