2013-02-12 19 views
9

मेरे पास निम्न के जैसा कोड है।क्या क्लास लेवल वैरिएबल पर उपयोग कथन का उपयोग करना बुरा व्यवहार है?

class MyController 
{ 
    [ThreadStatic] private DbInterface db; 

    public void ImportAllData() 
    { 
     using (db = new DbInterface()) 
     { 
      var records = PullData(); 
      PushData(records); 
     } 
    } 

    private DbRecord[] PullData() 
    { 
     return db.GetFromTableA(); 
    } 

    private void PushData(DbRecord[] records) 
    { 
     db.InsertIntoTableB(records); 
    } 
} 

विकल्प बनाए रखने के लिए बहुत अधिक बोझिल है।

class MyController 
{ 
    public void ImportAllData() 
    { 
     using (var db = new DbInterface()) 
     { 
      var records = PullData(db); 
      PushData(records, db); 
     } 
    } 

    private DbRecord[] PullData(DbInterface db) 
    { 
     return db.GetFromTableA(); 
    } 

    private void PushData(DbRecord[] records, DbInterface db) 
    { 
     db.InsertIntoTableB(records); 
    } 
} 

जहां तक ​​मैं देख सकता हूँ, मेरा पहला कार्यान्वयन:

  • धागा सुरक्षित (यह मानते हुए DbInterface धागा सुरक्षित है),
  • db चर छूने से किसी अन्य प्रक्रिया रोकता है, और
  • है
  • सुनिश्चित करता है कि db हमेशा अपवाद के दौरान भी निपटाया जाएगा।

क्या कक्षा के दायरे वाले चर पर using कथन का उपयोग करना बुरा व्यवहार है? क्या मुझे कुछ याद आया है?

+0

एक एक्सटेंशन का उपयोग कर माना जाता है? या आप इसे बहुत करने की योजना बना रहे हैं। –

+3

दिलचस्प बात यह है कि यदि आप कभी भी विन फॉर्म पेंटिंग कोड करते हैं, तो कम से कम उपयोग ब्लॉक के बाहर रेफरी पास करने के संबंध में ऑनपेंट और पेंट इवेंट बहुत कम हैं। आपको एक ग्राफिक्स संदर्भ पारित किया गया है जो आपके लिए आवंटित किया गया था और जिसका प्रबंधन/निपटान कॉलर द्वारा संभाला जाता है और इसलिए आप इसे वास्तविक चित्रकारी विधियों में स्वयं का निपटान नहीं करते हैं। – tcarvin

+0

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

उत्तर

10

व्यक्तिगत रूप से, मैं आपका दूसरा विकल्प पसंद करता हूं।

पहला डिजाइन वाला मुद्दा यह है कि आप प्रभावी ढंग से डिजाइन को अनावश्यक युग्मन जोड़ रहे हैं। आपके PullData और PushData विधियों का उपयोग अकेले नहीं किया जा सकता है - वे को की आवश्यकता होती है जो ImportAllData पर कॉल या db वैरिएबल को व्यवस्थित और व्यवस्थित करने वाली कुछ अन्य विधि को पहले कॉल किया जाएगा।

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

8

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

मैं पहले संस्करण का उपयोग नहीं करता।

sealed class MyImporter 
{ 
    private readonly DbInterface db; 

    public MyImporter(DbInterface db) 
    { 
     this.db = db; 
    } 

    public void ImportAllData() 
    { 
     var records = PullData(); 
     PushData(records); 
    } 

    private DbRecord[] PullData() 
    { 
     return db.GetFromTableA(); 
    } 

    private void PushData(DbRecord[] records) 
    { 
     db.InsertIntoTableB(records); 
    } 
} 

इस मामले में, संदर्भ पर वर्ग जिम्मेदारी का एक स्पष्ट भाग कर रहा है:

4

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

+1

+1: मैं कन्स्ट्रक्टर में निर्भरता इंजेक्शन भी जोड़ूंगा: सार्वजनिक MyImporter (DbInterface _db) { डीबी = _ डीबी; } – horgh

+0

@ कॉन्स्टेंटिन वासिलकोव, सहमत हैं, यह वास्तव में बहुत साफ है; यह वास्तव में कक्षा के अंदर निपटान की आवश्यकता को समाप्त करता है, साथ ही –

+0

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

0

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

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