एक फंक्शन खराब शैली के भीतर आंतरिक गुंजाइश ब्लॉक का उपयोग होता है?


10

ऐसे कुछ (काफी दुर्लभ) मामले हैं जिनमें जोखिम है:

  • एक चर का पुन: उपयोग करना जिसका पुन: उपयोग करने का इरादा नहीं है (उदाहरण 1 देखें),

  • या दूसरे के बजाय एक चर का उपयोग करना, शब्दार्थ के करीब (उदाहरण 2 देखें)।

उदाहरण 1:

var data = this.InitializeData();
if (this.IsConsistent(data, this.state))
{
    this.ETL.Process(data); // Alters original data in a way it couldn't be used any longer.
}

// ...

foreach (var flow in data.Flows)
{
    // This shouldn't happen: given that ETL possibly altered the contents of `data`, it is
    // not longer reliable to use `data.Flows`.
}

उदाहरण 2:

var userSettingsFile = SettingsFiles.LoadForUser();
var appSettingsFile = SettingsFiles.LoadForApp();

if (someCondition)
{
    userSettingsFile.Destroy();
}

userSettingsFile.ParseAndApply(); // There is a mistake here: `userSettingsFile` was maybe
                                  // destroyed. It's `appSettingsFile` which should have
                                  // been used instead.

इस जोखिम को एक गुंजाइश शुरू करके कम किया जा सकता है:

उदाहरण 1:

// There is no `foreach`, `if` or anything like this before `{`.

{
    var data = this.InitializeData();
    if (this.IsConsistent(data, this.state))
    {
        this.ETL.Process(data);
    }
}

// ...

// A few lines later, we can't use `data.Flows`, because it doesn't exist in this scope.

उदाहरण 2:

{
    var userSettingsFile = SettingsFiles.LoadForUser();

    if (someCondition)
    {
        userSettingsFile.Destroy();
    }
}

{
    var appSettingsFile = SettingsFiles.LoadForApp();

    // `userSettingsFile` is out of scope. There is no risk to use it instead of
    // `appSettingsFile`.
}

क्या यह गलत लगता है? क्या आप इस तरह के वाक्य रचना से बचेंगे? क्या शुरुआती लोगों द्वारा समझना मुश्किल है?


7
क्या आप तर्क दे सकते हैं कि प्रत्येक स्वतंत्र "स्कोप ब्लॉक" के बजाय इसकी अपनी विधि या कार्य होना चाहिए?
डैन पिचेलमैन

मैं कहूंगा कि "अक्सर" उतना अच्छा नहीं है जितना कि इसे लागू किया जा सकता है (लेकिन शायद "डिज़ाइन" समस्या नहीं है)। कभी-कभी डिजाइन द्वारा, यह अपरिहार्य है (उदाहरण के लिए अपवाद / संसाधन स्कूपिंग)।
जस्टिन सीसी

जवाबों:


35

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

कुछ व्यक्तिगत अनुभव द्वारा इसे वापस करने के लिए: कुछ साल पहले मुझे कोड की ~ 150K लाइनों के साथ एक C ++ विरासत परियोजना विरासत में मिली थी, और इसमें बिल्कुल इस तकनीक का उपयोग करते हुए कुछ तरीके शामिल थे। और लगता है क्या - उन तरीकों के सभी बहुत लंबे थे। जैसा कि हमने उस कोड में से अधिकांश को रिफलेक्ट किया है, विधियाँ छोटी और छोटी हो गई हैं, और मुझे पूरा यकीन है कि कोई "आंतरिक स्कोप" विधियाँ नहीं हैं; वे बस जरूरत नहीं है।


4
लेकिन यह बुरा क्यों है? कई नामित कार्य होने के कारण भी भ्रमित होते हैं।
क्रिस वान बाल

1
+1 वास्तव में, यदि आपको एक स्कोप की आवश्यकता है, तो संभव है कि आप एक विशेष क्रिया कर रहे हैं जिसे किसी फ़ंक्शन में निकाला जा सकता है। क्रिश, यह बहुत सारे और बहुत सारे कार्यों को बनाने के बारे में नहीं है, यह है कि जब ये मामले होते हैं (जहां एक ब्लॉक का दायरा दूसरे के साथ संघर्ष कर सकता है) आमतौर पर एक फ़ंक्शन का उपयोग किया जाना चाहिए। मैं इसे अन्य भाषाओं (अर्थात् जावास्क्रिप्ट, आईआईएफई के बजाय सादे 'पुराने कार्यों के साथ) में भी देखता हूं।
बेंजामिन ग्रुएनबाम

10
@KrisVanBael: "कई नामित कार्यों का होना भी भ्रामक है" - यदि आप वर्णनात्मक नामों का उपयोग करते हैं, तो इसके विपरीत बिल्कुल सच है। बहुत बड़े कार्यों का निर्माण सबसे शीर्ष कारण है कि कैसे कोड को बनाए रखना कठिन हो जाता है, और हद तक कठिन भी।
डॉक ब्राउन

2
यदि ऐसे कई कार्य हैं जो उन्हें विशिष्ट रूप से नाम देना एक समस्या बन जाते हैं, तो संभवत: उनमें से कुछ को एक नए प्रकार में रोल किया जा सकता है क्योंकि उनके मूल कार्य शरीर से उन्हें महत्वपूर्ण स्वतंत्रता हो सकती है। कुछ इतनी बारीकी से संबंधित हो सकते हैं कि उन्हें समाप्त किया जा सकता है। अचानक, वहाँ बहुत सारे कार्य नहीं हैं।
जस्टिनसी

3
फिर भी आश्वस्त नहीं हुए। अक्सर लंबे कार्य वास्तव में खराब होते हैं। लेकिन यह कहते हुए कि गुंजाइश की हर आवश्यकता के लिए एक अलग फ़ंक्शन की आवश्यकता होती है मेरे लिए बहुत काला और सफेद है।
क्रिश वान बाल

3

एक शुरुआती (और किसी भी प्रोग्रामर) के लिए यह सोचना बहुत आसान है:

  • एक चर का उपयोग नहीं करना जो प्रासंगिक नहीं है

सोचने की तुलना में:

  • कोड संरचनाओं को जोड़ना एक ऐसे चर का उपयोग न करने से स्वयं को रोकना है जो प्रासंगिक नहीं है।

इसके अलावा, एक पाठक के दृष्टिकोण से, ऐसे ब्लॉकों की कोई स्पष्ट भूमिका नहीं है: उन्हें हटाने से निष्पादन पर कोई प्रभाव नहीं पड़ता है। पाठक अपने सिर को खरोंच कर यह अनुमान लगाने की कोशिश कर सकता है कि कोडर क्या हासिल करना चाहता था।


2

एक स्कोप का उपयोग करना तकनीकी रूप से सही है। लेकिन अगर आप अपने कोड को अधिक पठनीय बनाना चाहते हैं, तो आपको उस भाग को दूसरी विधि में निकालना चाहिए और उस अर्थ को पूरा नाम देना चाहिए। इस तरह आप अपने चरों का दायरा दे सकते हैं और अपने कार्य का नाम भी दे सकते हैं।


0

मैं मानता हूं कि कोड गंध नहीं होने की तुलना में चर का पुन: उपयोग करना अधिक बार होता है। संभवतः इस तरह के कोड को छोटे, स्व-निहित, ब्लॉक में रिफैक्ट किया जाना चाहिए।

एक विशेष परिदृश्य, ओटीओएच, सी # में है, जब वे पॉपअप करते हैं - जब स्विच-केस निर्माण का उपयोग होता है। स्थिति को बहुत बारीकी से समझाया गया है: C # स्विच स्टेटमेंट विथ / विदाउट कर्ली ब्रैकेट ... क्या अंतर है?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.