एकल उदाहरणों और सिंगलटन डिज़ाइन पैटर्न के बीच अंतर करना महत्वपूर्ण है ।
एकल उदाहरण केवल एक वास्तविकता हैं। अधिकांश ऐप केवल एक समय में एक कॉन्फ़िगरेशन, एक यूआई एक समय में एक फ़ाइल सिस्टम, और इसी तरह से काम करने के लिए डिज़ाइन किए गए हैं। यदि बहुत अधिक स्थिति या डेटा बनाए रखा जाना है, तो निश्चित रूप से आप केवल एक उदाहरण रखना चाहेंगे और इसे यथासंभव लंबे समय तक जीवित रखेंगे।
सिंगलटन पैटर्न पैटर्न एक विशेष प्रकार का एकल उदाहरण है, विशेष रूप से एक:
- एक वैश्विक, स्थिर उदाहरण क्षेत्र के माध्यम से सुलभ;
- या तो प्रोग्राम इनिशियलाइज़ेशन पर या पहली पहुँच पर;
- कोई भी सार्वजनिक निर्माणकर्ता (सीधे संपर्क नहीं कर सकता);
- कभी भी स्पष्ट रूप से मुक्त नहीं किया गया (कार्यक्रम समाप्ति पर स्पष्ट रूप से मुक्त)।
यह इस विशिष्ट डिजाइन विकल्प के कारण है कि पैटर्न कई संभावित दीर्घकालिक समस्याओं का परिचय देता है:
- सार या इंटरफ़ेस वर्गों का उपयोग करने में असमर्थता;
- उपवर्ग में असमर्थता;
- आवेदन भर में उच्च युग्मन (संशोधित करने के लिए मुश्किल);
- परीक्षण करने में कठिनाई (यूनिट परीक्षणों में नकली / नकली नहीं हो सकती);
- उत्परिवर्तनीय स्थिति (व्यापक लॉकिंग की आवश्यकता होती है) के मामले में समानांतर करना मुश्किल;
- और इसी तरह।
इन लक्षणों में से कोई भी वास्तव में एकल उदाहरणों के लिए स्थानिक नहीं है, बस सिंगलटन पैटर्न है।
इसके बदले आप क्या कर सकते हैं? बस सिंगलटन पैटर्न का उपयोग न करें।
प्रश्न से उद्धरण:
विचार यह था कि ऐप में यह एक जगह है जो डेटा को संग्रहीत और समन्वयित रखता है, और फिर जो भी नई स्क्रीन खोली जाती हैं, वे सर्वर से विभिन्न सहायक डेटा के लिए दोहराए गए अनुरोधों के बिना, वहां से जो कुछ भी आवश्यक है, उसकी अधिकांश क्वेरी कर सकते हैं। लगातार सर्वर से अनुरोध करना बहुत अधिक बैंडविड्थ लेगा - और मैं प्रति सप्ताह हजारों डॉलर के अतिरिक्त इंटरनेट बिल की बात कर रहा हूं, ताकि यह अस्वीकार्य था।
इस अवधारणा का एक नाम है, जैसा कि आप संकेत की तरह लेकिन ध्वनि अनिश्चित के। इसे कैची कहा जाता है । यदि आप फैंसी प्राप्त करना चाहते हैं, तो आप इसे "ऑफ़लाइन कैश" या दूरस्थ डेटा की ऑफ़लाइन प्रतिलिपि कह सकते हैं।
एक कैश को एक सिंगलटन होने की आवश्यकता नहीं है। यदि आप एक से अधिक कैश इंस्टेंसेस के लिए समान डेटा लाने से बचना चाहते हैं, तो यह एक एकल उदाहरण होने की आवश्यकता हो सकती है; लेकिन इसका मतलब यह नहीं है कि आपको वास्तव में हर किसी के लिए सब कुछ उजागर करना होगा ।
पहली बात मैं कैश के विभिन्न कार्यात्मक क्षेत्रों को अलग-अलग इंटरफेस में अलग करता हूं । उदाहरण के लिए, मान लें कि आप Microsoft Access के आधार पर दुनिया का सबसे खराब YouTube क्लोन बना रहे हैं:
MSAccessCache
▲
|
+ ----------------- + ----------------- +
| | |
IMediaCache IProfileCache IPageCache
| | |
| | |
वीडियोपेज MyAccountPage MostPopularPage
यहां आपके पास कई प्रकार के इंटरफेस हैं जो विशिष्ट प्रकार के डेटा का वर्णन करते हैं, जिनके लिए किसी विशेष वर्ग को - मीडिया, उपयोगकर्ता प्रोफ़ाइल और स्थिर पृष्ठों (जैसे फ्रंट पेज) तक पहुंच की आवश्यकता हो सकती है। यह सब एक मेगा-कैश द्वारा कार्यान्वित किया जाता है , लेकिन आप इसके बजाय इंटरफेस को स्वीकार करने के लिए अपने व्यक्तिगत वर्गों को डिज़ाइन करते हैं, इसलिए उन्हें परवाह नहीं है कि उनके पास किस तरह का उदाहरण है। आप एक बार भौतिक आवृत्ति को इनिशियलाइज़ कर लेते हैं, जब आपका प्रोग्राम शुरू होता है, और उसके बाद बस कंस्ट्रक्टरों और सार्वजनिक संपत्तियों के माध्यम से इंस्टेंस (एक विशेष इंटरफ़ेस प्रकार के लिए) के आसपास से गुजरना शुरू करते हैं।
इसे डिपेंडेंसी इंजेक्शन कहा जाता है ; आपको बसंत या किसी विशेष आईओसी कंटेनर का उपयोग करने की आवश्यकता नहीं है, जब तक कि आपका सामान्य वर्ग डिज़ाइन कॉल करने वाले की निर्भरता को स्वीकार नहीं करता है, बजाय इसके कि वे स्वयं या वैश्विक स्थिति का संदर्भ दें ।
आपको इंटरफ़ेस-आधारित डिज़ाइन का उपयोग क्यों करना चाहिए? तीन कारण:
यह कोड को पढ़ना आसान बनाता है; आप स्पष्ट रूप से उन इंटरफेस से समझ सकते हैं जो निर्भर वर्गों पर निर्भर करते हैं।
यदि और जब आपको पता चलता है कि Microsoft Access डेटा बैक-एंड के लिए सबसे अच्छा विकल्प नहीं था, तो आप इसे कुछ बेहतर तरीके से बदल सकते हैं - मान लें कि SQL सर्वर।
यदि और जब आपको पता चलता है कि SQL सर्वर विशेष रूप से मीडिया के लिए सबसे अच्छा विकल्प नहीं है , तो आप सिस्टम के किसी अन्य भाग को प्रभावित किए बिना अपने कार्यान्वयन को तोड़ सकते हैं । यहीं से अमूर्तता की वास्तविक शक्ति सामने आती है।
यदि आप इसे एक कदम आगे ले जाना चाहते हैं तो आप स्प्रिंग (जावा) या यूनिटी (.NET) जैसे IoC कंटेनर (DI फ्रेमवर्क) का उपयोग कर सकते हैं। लगभग हर DI फ्रेमवर्क अपने स्वयं के जीवनकाल प्रबंधन को करेगा और विशेष रूप से आपको एक विशेष सेवा को एक एकल उदाहरण के रूप में परिभाषित करने की अनुमति देगा (अक्सर इसे "सिंगलटन" कहते हैं, लेकिन यह केवल परिचित के लिए है)। मूल रूप से ये चौखटे आपको ज्यादातर बंदर के कामों से बचाते हैं, जो मैन्युअल रूप से उदाहरणों के आसपास से गुजरते हैं, लेकिन वे कड़ाई से आवश्यक नहीं हैं। इस डिज़ाइन को लागू करने के लिए आपको किसी विशेष उपकरण की आवश्यकता नहीं है।
पूर्णता के लिए, मुझे यह इंगित करना चाहिए कि ऊपर का डिज़ाइन वास्तव में आदर्श नहीं है। जब आप कैश के साथ काम कर रहे हैं (जैसा कि आप हैं), तो आपको वास्तव में एक पूरी तरह से अलग परत होनी चाहिए । दूसरे शब्दों में, इस तरह एक डिजाइन:
+ - IMediaRepository
|
कैश (सामान्य) --------------- + - IProfileRepository
▲ |
| + - IPageRepository
+ ----------------- + ----------------- +
| | |
IMediaCache IProfileCache IPageCache
| | |
| | |
वीडियोपेज MyAccountPage MostPopularPage
इसका लाभ यह है कि आपको कभी भी अपने Cache
उदाहरण को तोड़ने की ज़रूरत नहीं है यदि आप रिफ्लेक्टर का फैसला करते हैं; आप यह बदल सकते हैं कि कैसे मीडिया को इसे केवल एक वैकल्पिक कार्यान्वयन खिलाकर संग्रहीत किया जाता है IMediaRepository
। यदि आप सोचते हैं कि यह एक साथ कैसे फिट बैठता है, तो आप देखेंगे कि यह अभी भी कभी-कभी केवल एक कैश का भौतिक उदाहरण बनाता है, इसलिए आपको कभी भी एक ही डेटा को दो बार लाने की आवश्यकता नहीं है।
यह कहने के लिए कोई भी नहीं है कि दुनिया के हर एक सॉफ्टवेयर को उच्च सामंजस्य और ढीले युग्मन के इन सटीक मानकों के अनुरूप होना चाहिए; यह परियोजना के आकार और दायरे, आपकी टीम, आपके बजट, समय सीमा आदि पर निर्भर करता है, लेकिन यदि आप पूछ रहे हैं कि सबसे अच्छा डिज़ाइन क्या है (एक सिंगलटन के स्थान पर उपयोग करने के लिए), तो यह वह है।
पीएस जैसा कि अन्य लोगों ने कहा है, आश्रित वर्गों के लिए शायद यह सबसे अच्छा विचार नहीं है कि वे कैश का उपयोग कर रहे हैं - यह एक कार्यान्वयन विवरण है जिसके बारे में उन्हें कभी ध्यान नहीं देना चाहिए। यह कहा जा रहा है, कुल मिलाकर वास्तुकला अभी भी बहुत ऊपर दिखाई देगा जैसा कि ऊपर चित्रित किया गया है, आप सिर्फ कैश के रूप में व्यक्तिगत इंटरफेस का उल्लेख नहीं करेंगे । इसके बजाय आप उन्हें सेवाओं या कुछ इसी तरह का नाम देंगे ।