C ++ में अनावश्यक घुंघराले ब्रेसिज़?


186

आज एक सहकर्मी के लिए कोड की समीक्षा करते समय मैंने एक अजीबोगरीब चीज देखी। उन्होंने अपने नए कोड को इस तरह घुंघराले ब्रेसिज़ के साथ घेर लिया था:

Constructor::Constructor()
{
   existing code

   {
      New code: do some new fancy stuff here
   }

   existing code
}

इससे क्या, यदि कोई हो, तो परिणाम क्या है? ऐसा करने का क्या कारण हो सकता है? यह आदत कहाँ से आती है?

संपादित करें:

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

पर्यावरण एम्बेडेड उपकरण है। सी ++ कपड़ों में लिगेसी सी कोड की एक बहुत कुछ है। बहुत सारे C बने हुए C ++ डेवलपर्स हैं।

कोड के इस भाग में कोई महत्वपूर्ण खंड नहीं हैं। मैंने इसे केवल कोड के इस भाग में देखा है। कोई बड़ी मेमोरी एलोकेशन नहीं की जाती है, बस कुछ झंडे लगाए जाते हैं, और कुछ थोड़ा ट्विडलिंग।

कोड जो घुंघराले ब्रेसिज़ से घिरा हुआ है, वह कुछ इस तरह है:

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) {
     return isInit;
   }
}

(कोड को बुरा मत मानना, बस घुंघराले ब्रेसिज़ से चिपके रहें ...;)) घुंघराले ब्रेसिज़ के बाद कुछ और बिट ट्विडलिंग, स्टेट चेकिंग और बेसिक सिग्नलिंग होती है।

मैंने उस लड़के से बात की और उसकी प्रेरणा चर के दायरे को सीमित करना था, नामकरण की झड़पें, और कुछ अन्य जो मैं वास्तव में नहीं उठा सकता था।

मेरे पीओवी से यह अजीब लगता है और मुझे नहीं लगता कि घुंघराले ब्रेसिज़ हमारे कोड में होने चाहिए। मैंने सभी उत्तरों में कुछ अच्छे उदाहरण देखे कि क्यों एक कोड को घुंघराले ब्रेसिज़ के साथ घेर सकते हैं, लेकिन क्या आपको कोड को इसके बजाय तरीकों में अलग नहीं करना चाहिए?


98
आपके सहयोगी का जवाब क्या था जब आपने उससे पूछा कि उसने ऐसा क्यों किया?
ग्राहम बोरलैंड

20
RAII पैटर्न के साथ काफी सामान्य। त्वरित अवलोकन: c2.com/cgi/wiki?ResourceAcquisitionIsInitialization
मार्सिन

9
मैं अनावश्यक घुंघराले ब्रेसिज़ से नफरत करता हूं
जैकनाड

8
क्या इनर ब्लॉक में कोई घोषणाएँ हुईं?
कीथ थॉम्पसन

15
शायद वह सिर्फ आसानी से 'गुना दूर है कि उनके संपादक में नया खंड करना चाहता था
विम

जवाबों:


281

यह कभी-कभी अच्छा होता है क्योंकि यह आपको एक नया दायरा देता है, जहाँ आप नए (स्वचालित) चरों को "साफ़" घोषित कर सकते हैं।

में C++ शायद इतना महत्वपूर्ण नहीं है क्योंकि आप कहीं भी नए चर पेश कर सकते हैं, लेकिन शायद आदत से है C, जहां आप C99 तक ऐसा नहीं कर सकते थे। :)

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


37
नई चर और पुरानी आदत का स्पष्ट उल्लेख के लिए +1
आर्नी

46
+1 संसाधनों को संभव के रूप में तेजी से मुक्त करने के लिए उपयोग किए जाने वाले ब्लॉक स्कोप का उपयोग करने के लिए
लियो

9
यह भी 'अगर (0)' एक ब्लॉक करने के लिए आसान है।
व्रध्न

मेरे कोड समीक्षक अक्सर मुझे बताते हैं कि मैं बहुत कम फ़ंक्शन / विधियाँ लिखता हूँ। उन्हें खुश रखने के लिए और खुद को खुश रखने के लिए (यानी असंबंधित चिंताओं, चर इलाके को अलग करने के लिए), मैं @unwind द्वारा विस्तृत रूप में इस तकनीक का उपयोग करता हूं।
ossandcad

21
@ossandcad, वे आपको बताते हैं कि आपके तरीके "बहुत कम" हैं? यह करना बहुत कठिन है। डेवलपर्स के 90% (स्वयं शामिल होने की संभावना) विपरीत समस्या है।
बेन ली

169

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


14
बेशक, वास्तव में उस ब्लॉक को केवल एक अलग फ़ंक्शन में बनाया जाना चाहिए।
ब्लूराजा -

8
ऐतिहासिक नोट: यह प्रारंभिक सी भाषा की एक तकनीक है जिसने स्थानीय अस्थायी चर बनाने की अनुमति दी है।
थॉमस मैथ्यूज

12
मुझे कहना है - हालाँकि मैं अपने उत्तर से संतुष्ट हूँ, यह वास्तव में यहाँ सबसे अच्छा जवाब नहीं है; बेहतर उत्तर RAII का स्पष्ट रूप से उल्लेख करते हैं, क्योंकि यह मुख्य कारण है कि आप एक विध्वंसक को एक विशिष्ट बिंदु पर क्यों बुलाना चाहते हैं। यह "वेस्ट में सबसे तेज़ बंदूक" के एक मामले की तरह लगता है: मैंने काफी तेजी से पोस्ट किया कि मुझे कुछ शुरुआती उत्तरों की तुलना में तेजी से बढ़त हासिल करने के लिए "गति" प्राप्त हुई। ऐसा नहीं है कि मैं शिकायत कर रहा हूँ! :-)
रुख

7
@ BlueRaja-DannyPflughoeft आपकी देखरेख कर रहे हैं। "इसे एक अलग फ़ंक्शन में रखें" हर कोड समस्या का समाधान नहीं है। इन ब्लॉकों में से एक में कोड को आसपास के कोड के साथ कसकर जोड़ा जा सकता है, इसके कई चर को छूते हुए। C फ़ंक्शन का उपयोग करना, जिसमें पॉइंटर संचालन की आवश्यकता होती है। इसके अलावा, नहीं हर कोड स्निपेट (या होना चाहिए) पुन: प्रयोज्य है, और कभी-कभी कोड अपने आप भी समझ में नहीं आ सकता है। मैं कभी-कभी C89 में forअल्पकालिक बनाने के लिए अपने बयानों के चारों ओर ब्लॉक लगा देता हूं int i;। निश्चित रूप से आप यह सुझाव नहीं दे रहे हैं कि प्रत्येक forको एक अलग फ़ंक्शन में होना चाहिए?
एंडर्स Sjöqvist

101

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

मेरे उत्पादन कोड में, मैंने कुछ इस तरह लिखा है:

void f()
{
   //some code - MULTIPLE threads can execute this code at the same time

   {
       scoped_lock lock(mutex); //critical section starts here

       //critical section code
       //EXACTLY ONE thread can execute this code at a time

   } //mutex is automatically released here

  //other code  - MULTIPLE threads can execute this code at the same time
}

जैसा कि आप देख सकते हैं, इस तरह, आप scoped_lock एक फ़ंक्शन में उपयोग कर सकते हैं और एक ही समय में, अतिरिक्त ब्रेस का उपयोग करके इसके दायरे को परिभाषित कर सकते हैं। यह सुनिश्चित करता है कि भले ही अतिरिक्त ब्रेसिज़ के बाहर कोड को एक साथ कई थ्रेड द्वारा निष्पादित किया जा सकता है , ब्रेसिज़ के अंदर कोड को एक समय में ठीक एक थ्रेड द्वारा निष्पादित किया जाएगा ।


1
मुझे लगता है कि यह सिर्फ क्लीनर है: scoped_lock लॉक (mutex) // महत्वपूर्ण अनुभाग कोड फिर lock.unlock ()।
कड़ाके की धूप

17
@szielenski: क्या होगा यदि महत्वपूर्ण खंड से कोड अपवाद फेंकता है? या तो म्यूटेक्स को हमेशा के लिए बंद कर दिया जाएगा, या कोड उस क्लीनर के रूप में नहीं होगा जैसा आपने कहा था।
नवाज

4
@ नवाज़: @ szielenski का दृष्टिकोण अपवाद के मामले में म्यूटेक्स को बंद नहीं करेगा। उन्होंने यह भी एक का उपयोग करता है scoped_lockकि अपवाद पर नष्ट हो जाएगा। मैं आमतौर पर लॉक के लिए एक नया दायरा शुरू करना पसंद करता हूं, लेकिन कुछ मामलों में unlockयह बहुत उपयोगी है। उदाहरण के लिए महत्वपूर्ण खंड के भीतर एक नया स्थानीय चर घोषित करना और फिर बाद में इसका उपयोग करना। (मुझे पता है कि मुझे देर हो गई है, लेकिन सिर्फ पूर्णता के लिए ...)
स्टीफन

51

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

हालाँकि, ऐसा करने का एक और बढ़िया कारण है।

यह केवल एक विशेष (उप) उद्देश्य को प्राप्त करने वाले कोड के एक ब्लॉक को अलग करना है। यह दुर्लभ है कि एक एकल कथन एक कम्प्यूटेशनल प्रभाव प्राप्त करता है जो मुझे चाहिए; आमतौर पर यह कई लेता है। उन लोगों को ब्लॉक में रखना (टिप्पणी के साथ) मुझे पाठक (अक्सर बाद की तारीख में खुद को) बताने की अनुमति देता है:

  • इस चंक का एक सुसंगत वैचारिक उद्देश्य है
  • यहाँ सभी कोड की आवश्यकता है
  • और यहाँ एक टिप्पणी के बारे में है।

जैसे

{  // update the moving average
   i= (i+1) mod ARRAYSIZE;
   sum = sum - A[i];
   A[i] = new_value;
   sum = sum + new_value;
   average = sum / ARRAYSIZE ;  
}

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

यदि आप भाग्यशाली हैं, तो आपके संपादक के पास एक गुना / अनफोल्ड फ़ंक्शन होगा जो आपको ब्लॉक को छिपाने देगा।

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


23

एक कारण यह हो सकता है कि नए घुंघराले ब्रेस ब्लॉक के अंदर घोषित किसी भी चर का जीवनकाल इस ब्लॉक तक ही सीमित है। एक और कारण जो मन में आता है वह है पसंदीदा संपादक में कोड फोल्डिंग का उपयोग करना।


17

यह एक if(या whileआदि ..) ब्लॉक के समान है, बस बिना if । दूसरे शब्दों में, आप एक नियंत्रण संरचना शुरू किए बिना एक गुंजाइश का परिचय देते हैं।

यह "स्पष्ट स्कूपिंग" आमतौर पर निम्नलिखित मामलों में उपयोगी है:

  1. नाम बंद से बचने के लिए।
  2. गुंजाइश के लिए using
  3. नियंत्रण करने के लिए जब विध्वंसक कहा जाता है।

उदाहरण 1:

{
    auto my_variable = ... ;
    // ...
}

// ...

{
    auto my_variable = ... ;
    // ...
}

यदि दो अलग-अलग चर के लिए my_variableविशेष रूप से अच्छा नाम होता है जो एक दूसरे से अलगाव में उपयोग किए जाते हैं, तो स्पष्ट रूप से स्कोपिंग आपको नाम के टकराव से बचने के लिए सिर्फ एक नए नाम का आविष्कार करने से बचने की अनुमति देता है।

इससे आप my_variableदुर्घटना से इसके इच्छित दायरे से बाहर निकलने से भी बच सकते हैं ।

उदाहरण 2:

namespace N1 { class A { }; }
namespace N2 { class A { }; }

void foo() {

    {
        using namespace N1;
        A a; // N1::A.
        // ...
    }

    {
        using namespace N2;
        A a; // N2::A.
        // ...
    }

}

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

उदाहरण 3:

{
    MyRaiiClass guard1 = ...;

    // ...

    {
        MyRaiiClass guard2 = ...;
        // ...
    } // ~MyRaiiClass for guard2 called.

    // ...

} // ~MyRaiiClass for guard1 called.

यह उन मामलों में RAII के लिए महत्वपूर्ण हो सकता है जब फ़ंक्शंस या नियंत्रण संरचनाओं की सीमाओं पर संसाधनों को मुक्त करने की आवश्यकता स्वाभाविक रूप से "गिरती" नहीं है।


15

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


14

बाकी सभी ने पहले से ही स्कूपिंग, आरएआई आदि व्यवसायों को सही ढंग से कवर किया है, लेकिन जब से आप एक एम्बेडेड वातावरण का उल्लेख करते हैं, तो एक और संभावित कारण है:

हो सकता है कि डेवलपर इस कंपाइलर के रजिस्टर आबंटन पर भरोसा नहीं करता हो या एक बार के दायरे में स्वचालित चर की संख्या को सीमित करके स्टैक फ्रेम आकार को स्पष्ट रूप से नियंत्रित करना चाहता हो।

यहाँ isInitसंभवतः स्टैक पर होगा:

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) {
     return isInit;
   }
}

यदि आप घुंघराले ब्रेसिज़ को बाहर निकालते हैं, isInitतो स्टैक फ्रेम में स्थान को आरक्षित किया जा सकता है , भले ही इसका संभावित रूप से पुन: उपयोग किया जा सकता है: यदि समान स्थानीय स्कोप के साथ बहुत सारे स्वचालित चर हैं, और आपका स्टैक आकार सीमित है, तो यह एक समस्या हो सकती है।

इसी तरह, यदि आपका वेरिएबल एक रजिस्टर को आवंटित किया गया है, तो स्कोप से बाहर जाने पर एक मजबूत संकेत देना चाहिए कि रजिस्टर अब फिर से उपयोग के लिए उपलब्ध है। आपको यह पता लगाने के लिए कि क्या यह वास्तविक अंतर बनाता है (और इसे प्रोफाइल करें - या स्टैक ओवरफ्लो के लिए देखते हैं - यह देखने के लिए कि क्या यह अंतर वास्तव में मायने रखता है) के साथ उत्पन्न किए गए कोडांतरक को देखना होगा।


+1 अच्छा बिंदु, हालांकि मुझे यकीन है कि आधुनिक संकलक हस्तक्षेप के बिना यह अधिकार प्राप्त करते हैं। (IIRC - कम से कम गैर-संकलित कंपाइलरों के लिए - उन्होंने '99 'कीवर्ड को '99 तक वापस ले लिया' को नजरअंदाज कर दिया क्योंकि वे हमेशा आपके मुकाबले बेहतर काम कर सकते थे।)
Rup

11

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

// if (false) or if (0) 
{
   //experimental optimization  
}

यह अभ्यास डिबगिंग, एम्बेडेड डिवाइस, या व्यक्तिगत कोड जैसे कुछ संदर्भों में उपयोगी है।


10

मैं "रुख" से सहमत हूं। यदि आप C में स्कोप के विभिन्न स्तरों की अच्छी व्याख्या चाहते हैं, तो इस पोस्ट को देखें:

सी एप्लीकेशन में स्कोप के विभिन्न स्तर

सामान्य तौर पर, "ब्लॉक स्कोप" का उपयोग मददगार होता है यदि आप केवल एक अस्थायी चर का उपयोग करना चाहते हैं जिसे आपको फ़ंक्शन कॉल के जीवनकाल के लिए ट्रैक रखने की आवश्यकता नहीं है। इसके अतिरिक्त, कुछ लोग इसका उपयोग करते हैं ताकि आप सुविधा के लिए कई स्थानों पर एक ही चर नाम का उपयोग कर सकें, हालांकि यह आमतौर पर एक अच्छा विचार नहीं है। उदाहरण के लिए:

int unusedInt = 1;

int main(void) {
  int k;

  for(k = 0; k<10; k++) {
    int returnValue = myFunction(k);
    printf("returnValue (int) is: %d (k=%d)",returnValue,k);
  }

  for(k = 0; k<100; k++) {
    char returnValue = myCharacterFunction(k);
    printf("returnValue (char) is: %c  (k=%d)",returnValue,k);
  }

  return 0;
}

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

मैं यह नहीं कह सकता कि यह सामान्य रूप से एक अच्छा विचार है (यानी: आपको शायद ब्लॉक-टू-ब्लॉक से चर नामों का बार-बार उपयोग नहीं करना चाहिए), लेकिन सामान्य तौर पर, यह समय बचाता है और आपको प्रबंधन करने से बचने की सुविधा देता है पूरे समारोह में वापसी का मूल्य।

अंत में, कृपया मेरे कोड नमूने में प्रयुक्त चर का दायरा नोट करें:

int:  unusedInt:   File and global scope (if this were a static int, it would only be file scope)
int:  k:           Function scope
int:  returnValue: Block scope
char: returnValue: Block scope

व्यस्त प्रश्न, यार। मैंने कभी 100 अप नहीं किया है। इस सवाल में ऐसा क्या खास है? अच्छा लिंक। C ++ से C अधिक मूल्यवान है।
वोल्फपैक'08

5

तो, "अनावश्यक" घुंघराले ब्रेसिज़ का उपयोग क्यों करें?

  • "स्कोपिंग" प्रयोजनों के लिए (जैसा कि ऊपर बताया गया है)
  • एक तरह से कोड को अधिक पठनीय बनाना (बहुत अधिक उपयोग करना पसंद है #pragma "अनुभागों या परिभाषित करना " जिसकी कल्पना की जा सकती है)
  • क्योंकि, तुम कर सकते हो। इतना ही आसान।

PS यह BAD कोड नहीं है; यह 100% वैध है। तो, यह बल्कि (असामान्य) स्वाद की बात है।


5

संपादन में कोड को देखने के बाद, मैं कह सकता हूं कि अनावश्यक ब्रैकेट संभवतः (मूल कोडर्स दृश्य में) 100% स्पष्ट हो सकते हैं कि क्या होगा यदि / उसके दौरान क्या होगा, यहां तक ​​कि अब यह केवल एक पंक्ति है, यह हो सकता है अधिक लाइनें बाद में, और कोष्ठक की गारंटी देता है कि आप एक त्रुटि नहीं करेंगे।

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) {
     return isInit;
   }
   return -1;
}

यदि उपर्युक्त मूल था, और "अतिरिक्त" को हटाने के परिणामस्वरूप:

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) 
     return isInit;
   return -1;
}

फिर, बाद में संशोधन इस तरह दिख सकता है:

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) 
     CallSomethingNewHere();
     return isInit;
   return -1;
}

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


4

जब वे दायरे से बाहर जाते हैं, तो ऑब्जेक्ट्स स्वचालित रूप से नष्ट हो जाते हैं ...


2

उपयोग का एक और उदाहरण यूआई से संबंधित कक्षाएं हैं, विशेष रूप से क्यूटी।

उदाहरण के लिए, आपके पास कुछ जटिल UI और बहुत सारे विजेट हैं, उनमें से प्रत्येक का नामकरण, लेआउट और आदि के बजाय उन्हें नामकरण दिया गया है space1, space2, spaceBetween, layout1, ... आप स्वयं को लिए गैर-वर्णनात्मक नामों से बचा सकते हैं जो केवल दो-तीन पंक्तियों में मौजूद हैं कोड।

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

// Start video button 
{ 
   <here the code goes> 
}
// Stop video button
{
   <...>
}
// Status label
{
   <...>
}

यह नहीं कह सकता कि यह सबसे अच्छा अभ्यास है, लेकिन यह विरासत कोड के लिए अच्छा है।

इन समस्याओं को तब मिला जब बहुत से लोगों ने अपने घटकों को UI में जोड़ा और कुछ विधियां वास्तव में बड़े पैमाने पर बन गईं, लेकिन कक्षा के अंदर 40 ऑन-लाइफ-उपयोग विधियों को बनाना व्यावहारिक नहीं है जो पहले से ही गड़बड़ है।

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