2009-07-03 10 views
6

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

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

  1. तोड़ विन्यास वस्तु:

    तो, मैं तीन विकल्प यहाँ देखें। यह कम से कम मुझे आयात-समय निर्भरता के रूप में डेटाबेस को हटाने की अनुमति देगा।

  2. कॉन्फ़िगरेशन ऑब्जेक्ट को एक गैर-सिंगलटन बनाएं और इसे उन ऑब्जेक्ट्स को पास करें जिन्हें इसकी आवश्यकता है। मुझे लगता है कि यह हमारी अल्पकालिक आवश्यकताओं को बेहतर ढंग से संबोधित करता है, लेकिन मुझे लगता है कि इसमें काफी समय लगेगा।
  3. ऐसा कुछ करें जिसे मैंने नहीं सोचा था कि आप अपने उत्तर में सुझाव देते हैं। :-)

तो मैं क्या करूँ?

उत्तर

5

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

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

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

5

अपने कोड को देखे बिना जानना मुश्किल है, लेकिन आप जो भी कहते हैं वह क्यों नहीं करते - क्या यह बढ़ता है? पहले चरण 1 करें, डेटाबेस को विभाजित करें।

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

उम्मीद है कि आप सिंगलटन में जो कुछ भी गायब हो जाते हैं, उसे चरण-दर-चरण कम कर सकते हैं, बिना किसी चरण में एक बड़ा समय कर चुकाए।

उदाहरण के लिए कॉन्फ़िगरेशन के कुछ हिस्सों स्वतंत्र होने पर कॉन्फ़िगरेशन का एक हिस्सा सिंगलटन को एक समय में बनाया जा सकता है। तो हो सकता है कि GUI कॉन्फ़िगरेशन सिंगलटन छोड़ दिया हो, जबकि फ़ाइल कॉन्फ़िगरेशन रीफैक्टर हो या कुछ ऐसा ही हो?

+0

मुझे लगता है कि * ऐसा कुछ है जिसे मैंने नहीं सोचा था। ऑब्जेक्ट को तोड़कर, डी-सिंगलटन (यदि यह एक शब्द है) के लिए आसान हो जाता है। –

+0

desingulate के बारे में कैसे? –

+1

या शायद बहुवचन? :-) –

2

विकल्प 1 मैं अपने सभी ऐप्स में करता हूं: कॉन्फ़िगरेशन ऑब्जेक्ट सिंगलटन और डेटाबेस ऑब्जेक्ट मांग या इंजेक्शन पर बनाए जाते हैं।

एक सिंगलटन के रूप में कॉफ़िगरेशन ऑब्जेक्ट रखने के लिए हमेशा मेरे लिए एकदम सही फिट रहा है। केवल एक कॉन्फ़िगरेशन फ़ाइल है और जब मैं एप्लिकेशन शुरू करता हूं तो मैं हमेशा इसे पढ़ना चाहता हूं।

+0

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

+0

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

2

कीजिए तथ्य यह है कि मैं किसी भी अजगर पता नहीं है, इसलिए मुझे आशा है कि किसी भी छद्म कोड समझ में आता है ...

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

एक बार मुझे मिल गया था कि अब तक मैं एक नया, आवरण सिंगलटन कि विन्यास वर्ग के तरीकों को उजागर करता बनाएंगे:

class ConfigurationWrapper : IConfigurationClass 
{ 
    public static property ConfigurationWrapper Instance; 

    public property IConfigurationClass InnerClass; 

    public method GetDefaultWindowWidth() 
    { 
     return InnerClass.GetDefaultWindowWidth(); 
    } 

    etc... 
} 

बहुत पहली बात आवेदन करता है अब का एक उदाहरण इंजेक्षन है रैपर में कॉन्फ़िगरेशन क्लास।

ConfigurationClass config = new ConfigurationClass() 
ConfigurationWrapper.Instance.InnerClass = config; 

अंत में आप वर्गों है कि वर्तमान में आवरण सिंगलटन (जो एक त्वरित खोज हो सकता है और बदल दिया जाना चाहिए) के लिए खत्म हो सिंगलटन पर भरोसा कर सकते हैं। अब आप चरण 2 को पूरा करने के लिए कॉन्फ़िगरेशन ऑब्जेक्ट को कॉन्फ़िगरेशन ऑब्जेक्ट में ले जाने के लिए कक्षाओं को एक बार में परिवर्तित कर सकते हैं। आपके पास ऐसा करने का समय नहीं है, जो रैपर सिंगलटन का उपयोग कर सकता है। एक बार जब आप उन्हें ऊपर ले जाते हैं तो आप रैपर से छुटकारा पा सकते हैं।

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

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