2011-12-21 21 views
9

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

मैं क्रॉस प्लेटफार्म (विंडोज एक्सपी/विस्टा/7, विंडोज मोबाइल 6.x, विंडोज सीई 5, विंडोज सीई 6) होने के लिए एक एप्लीकेशन विकसित कर रहा हूं। प्रक्रिया के हिस्से के रूप में मैं अलग-अलग परियोजनाओं में कोड को फिर से फैक्टर कर रहा हूं, कोड डुप्लिकेशन को कम करने के लिए, और इसलिए इनटाइटल सिस्टम की गलतियों को ठीक करने का मौका।

आवेदन के इस तरह का एक हिस्सा अलग किया जा रहा है, यह एक प्रोफाइल प्रबंधक है। यह प्रोजेक्ट प्रोफाइल संग्रहीत करने के लिए ज़िम्मेदार है। इसमें Profile कक्षा है जिसमें कुछ कॉन्फ़िगरेशन डेटा शामिल हैं जो एप्लिकेशन के सभी हिस्सों द्वारा उपयोग किया जाता है। इसमें ProfileManager कक्षा है जिसमें Profiles शामिल है। ProfileManager हार्ड ड्राइव पर अलग-अलग XML फ़ाइलों के रूप में Profiles को पढ़/सहेज लेगा, और एप्लिकेशन को "सक्रिय" Profile को पुनर्प्राप्त करने और सेट करने की अनुमति देगा। सरल।

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

इसका मतलब है कि मैं आवश्यकतानुसार सिस्टम के विभिन्न हिस्सों के लिए कॉन्फ़िगरेशन पुनर्प्राप्त करने के लिए ProfileManager.Instance.ActiveProfile पर जा सकता था। प्रत्येक जीयूआई प्रोफ़ाइल में बदलाव भी कर सकता है, इसलिए प्रत्येक जीयूआई में एक सेव बटन था, इसलिए उन सभी को ProfileManager.Instance.SaveActiveProfile() विधि तक पहुंच थी।

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

पी। मुझे कॉम्पैक्ट फ्रेमवर्क 3.5 के खिलाफ एप्लिकेशन बनाना है, जो सामान्य नेट फ्रेमवर्क कक्षाओं के बहुत से सीमित करता है जिसका उपयोग किया जा सकता है।

+6

मैं बस अपनी पुरानी आदतों में फंस सकता हूं, लेकिन मैं इसे एक अच्छा उदाहरण के रूप में देखता हूं जहां सिंगलटन का उपयोग किया जाना चाहिए। –

+0

यह वास्तव में एक सिंगलटन उदाहरण के लिए आदर्श मामले की तरह लगता है। – msarchet

+0

सभी उत्तरों के लिए धन्यवाद, ऐसा लगता है कि यह सिंगलटन का उपयोग करने के लिए एक उचित जगह है। फैक्ट्री/निर्भरता इंजेक्शन पर प्रतिक्रिया को ध्यान में रखा जाएगा, हालांकि यह एप्लिकेशन पृष्ठभूमि में चलाएगा, इसलिए मैं इसे सादगी और प्रदर्शन दोनों के लिए सिंगलटन के रूप में छोड़ दूंगा। – JonWillis

उत्तर

8

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

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

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

+0

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

2

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

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

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

+0

आपके इनपुट के लिए धन्यवाद, "सिंगलटन" और सिर्फ "सिंगल रेफरेंस" नहीं होने के साथ मेरी चिंताओं, जैसा कि आप बताते हैं, कई तरीकों से अतिरिक्त पैरामीटर रखते हैं। जो अंततः एक गन्दा व्यवसाय बन जाता है। – JonWillis

5

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

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

आपके प्रत्यक्ष प्रश्न का उत्तर नहीं देता है, लेकिन यह भविष्य में शून्य के करीब एक बदलाव का प्रभाव डालता है।

+0

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

संबंधित मुद्दे