2010-07-03 22 views
7

मैं कुछ समय के लिए एक वेब डेवलपर किया गया है अब ASP.NET और सी # का उपयोग कर, मैं कोशिश करते हैं और सर्वोत्तम प्रथाओं का उपयोग करके अपने कौशल को बढ़ाने के लिए चाहते हैं।सिंगलटन पैटर्न के लिए विकल्प?

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

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

धन्यवाद ब्रेंडन

+0

संभावित डुप्लिकेट [क्या GOF सिंगलटन पैटर्न के लिए कोई व्यवहार्य विकल्प हैं?] (Http://stackoverflow.com/questions/162042/are-there-any-viable-alternatives-to-the-gof-singleton- पैटर्न) –

उत्तर

6

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

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

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

public class Foo 
{ 
    private IAppConfiguration Configuration { get; set; } 

    public Foo() : this(null) { } 

    public Foo(IAppConfiguration config) 
    { 
     this.Configuration = config ?? AppConfiguration.Instance; 
    } 

    public void Bar() 
    { 
     var value = this.Config.SomeMaximum; 
     ... 
    } 
}  
+0

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

+0

यह वह दृष्टिकोण है जिसे मैंने माइग्रेट किया है, हालांकि मेरे कॉन्फ़िगरेशन इंटरफ़ेस को मेरे डी कंटेनर में सिंगलटन के रूप में दोनों दुनिया के सर्वश्रेष्ठ के लिए पंजीकृत किया गया है। यह अभी भी सिंगलटन कार्यान्वयन का एकमात्र उदाहरण है, हालांकि मुझे सहज महसूस होता है। – tvanfosson

1

सिंगलटन पैटर्न की एक अच्छी चर्चा नहीं है, और यहाँ उदाहरण कोडिंग ... http://en.wikipedia.org/wiki/Singleton_pattern भी यहाँ देखें ... http://en.wikipedia.org/wiki/Dependency_injection

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

+0

मैं इकाई को भी परीक्षण करना चाहता हूं, लेकिन यह नहीं पता कि इकाई को सिंगलटन पैटर्न का परीक्षण कैसे किया जाए? –

1

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

आदर्श रूप से आपकी सेटिंग्स एक उच्च स्तरीय स्थान पर सदस्य चर होना चाहिए, उदाहरण के लिए एप्लिकेशन ऑब्जेक्ट जो आपके द्वारा उत्पन्न वेबपृष्ठों का मालिक है। पेज तब ऐप से सेटिंग्स के लिए पूछ सकते हैं, या पेज सेटिंग्स के रूप में सेटिंग्स को पास कर सकते हैं।

+0

डिजाइन पैटर्न पाठ्यक्रम में मैंने भाग लिया, सिंगलटन पहले सिखाया गया था। यही कारण है कि हर कोई इसे याद करता है। –

+3

@ ब्रायन: और उस पैटर्न का वर्णन http://sites.google.com/site/steveyegge2/singleton-considered-stupid – wRAR

+0

पर किया गया है क्या आपके पास वर्णित कोड का नमूना मिला है? या एक लिंक? –

0

इस समस्या से संपर्क करने का एक तरीका है, इसे DAL समस्या के रूप में बंद करना है।

जो भी वर्ग/वेब पेज, आदि config सेटिंग्स का उपयोग करने के लिए एक IConfigSettingsService पर निर्भरता की घोषणा करनी चाहिए की जरूरत है (कारखाना/भंडार/जो कुछ-आप की तरह-टू-कॉल-उन्हें)।

private IConfigSettingsService _configSettingsService; 

public WebPage(IConfigSettingsService configSettingsService) 
{ 
    _configSettingsService = configSettingsService; 
} 

तो अपने वर्ग इस तरह सेटिंग्स मिलेगा:

ConfigSettings _configSettings = _configSettingsService.GetTheOnlySettings(); 

ConfigSettingsService कार्यान्वयन निर्भरता जो दल वर्ग है होगा। वह दल ConfigSettings ऑब्जेक्ट को कैसे पॉप्युलेट करेगा? कौन परवाह करता है।

  • शायद यह एक डेटाबेस या .config xml फ़ाइल से एक ConfigSettings, हर बार हो जाएगी।

  • शायद यह पहली बार ऐसा करता है लेकिन फिर बाद की कॉल के लिए एक स्थिर _configSettings पॉप्युलेट करता है।

  • शायद यह रेडिस से सेटिंग्स प्राप्त करेगा। अगर कुछ इंगित करता है कि सेटिंग्स बदल गई हैं तो दाल, या कुछ बाहरी, रेडिस अपडेट कर सकते हैं। (यह दृष्टिकोण यदि आप सेटिंग्स का उपयोग कर एक से अधिक ऐप्लिकेशन है उपयोगी होगा।

जो भी करता है, अपने ही निर्भरता एक गैर सिंगलटन सेवा इंटरफेस है। यही कारण है कि उपहास करने के लिए बहुत आसान है। अपने परीक्षणों में आप क्या आप इसे जो कुछ भी चाहते हैं उसके साथ एक ConfigSettings वापस कर सकते हैं)।

हकीकत में यह अधिक संभावना MyPageBase जाएगा जो IConfigSettingsService निर्भरता है, लेकिन यह बस के रूप में आसानी से एक वेब सेवा, खिड़कियां सेवा, MVC somewhatsit, या ऊपर के सभी हो सकता है।

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