2010-10-06 15 views
22

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

उत्तर

18

इस बारे में एक महान लेख Singletons are Pathological Liars है। यह एक साधारण उदाहरण का उपयोग करके वर्णन करता है, सिंगलेट का उपयोग करके परीक्षण अप्रत्याशित रूप से कठिन क्यों है।

+4

लिंक टूटा हुआ है। – Emil

+2

यहां ठीक काम करता है। –

+0

ग्रेट आलेख, +1। एकमात्र चीज जिसे मैं लेख को बदलना चाहता हूं वह अंतिम उदाहरण है ... मेरे लिए यह क्रेडिट कार्ड प्रसंस्करण पर चार्ज() विधि के लिए अधिक समझ में आता है और यह कार्ड और पैरामीटर के रूप में राशि लेता है :) – rmeador

2

This Google Techtalk एकमात्र और वैश्विक राज्य के साथ समस्याओं का वर्णन है जब यह इकाई परीक्षण के लिए आता है की एक बहुत अच्छा काम करता है।

-2

मुझे यह कभी भी याद नहीं है, लेकिन मुझे संदेह है कि समस्या यह तथ्य है कि आप केवल एक बना सकते हैं। कुछ मामलों में, यह कोई समस्या नहीं हो सकती है, बस इसे सामान्य रूप से जांचें।

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

5

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

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

4

क्योंकि सिंगलटन एक OOPish वैश्विक चर रहा है। असल में, सिंगलटन (प्रत्यक्ष या परोक्ष) के उपयोग पर निर्भर सभी कार्यों नियतात्मक होने की गारंटी नहीं कर रहे हैं (अर्थात आप समारोह में एक ही आदानों टी हर रन के लिए एक ही आउटपुट वापस जाने के लिए उम्मीद नहीं कर सकते)।

2

Singletons कई कारणों से एक समस्या है: वे एक सेवा लोकेटर, जो "मुझे उन में से एक प्राप्त" करने के लिए एक तंत्र प्रदान करता है का एक विशेष मामला हो

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

टीएल; डीआर एक ही वस्तु सभी परीक्षणों के बीच साझा की जाती है, जो दर्द हो सकती है।

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

बेशक यदि "सूची" "हटाएं" से पहले चलता है, तो शायद यह ठीक है। यदि "हटाएं" "सूची" से पहले चलता है, तो हम संघर्ष करते हैं क्योंकि हटाने के लिए कुछ भी नहीं है। (परिणाम उस क्रम के आधार पर बदलते हैं जिसमें परीक्षण चलाए जाते हैं।)

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

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