paint-brush
अपने कोड के बदबूदार हिस्सों को कैसे खोजें [भाग XXII]द्वारा@mcsee
783 रीडिंग
783 रीडिंग

अपने कोड के बदबूदार हिस्सों को कैसे खोजें [भाग XXII]

द्वारा Maximiliano Contieri8m2022/08/29
Read on Terminal Reader
Read this story w/o Javascript

बहुत लंबा; पढ़ने के लिए

यह गंध करता है क्योंकि ऐसे कई उदाहरण हैं जहां इसे संपादित या सुधार किया जा सकता है।

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - अपने कोड के बदबूदार हिस्सों को कैसे खोजें [भाग XXII]
Maximiliano Contieri HackerNoon profile picture

कोड गंध एक क्लासिक हैं।

यह गंध करता है क्योंकि ऐसे कई उदाहरण हैं जहां इसे संपादित या सुधार किया जा सकता है।


इनमें से अधिकतर गंध कुछ गलत होने का संकेत मात्र हैं। वे अनिवार्य रूप से निश्चित नहीं हैं ... (हालांकि आपको इसे देखना चाहिए।)


पिछला कोड बदबू आ रही है

चलो जारी रखते है...


कोड गंध 106 - उत्पादन निर्भर कोड

उत्पादन परिवेश के लिए IFs जाँच न जोड़ें।

TL; DR: उत्पादन से संबंधित शर्तों को जोड़ने से बचें

समस्या

  • तेजी से विफल सिद्धांत उल्लंघन
  • टेस्टेबिलिटी की कमी

समाधान

  1. यदि पूरी तरह से आवश्यक हो, तो वातावरण को मॉडल करें और उन सभी का परीक्षण करें।

संदर्भ

कभी-कभी, हमें विकास और उत्पादन में अलग-अलग व्यवहार बनाने की आवश्यकता होती है।

उदाहरण के लिए पासवर्ड की ताकत।

इस मामले में, हमें पर्यावरण को ताकत की रणनीति के साथ कॉन्फ़िगर करने और रणनीति का परीक्षण करने की आवश्यकता है, न कि पर्यावरण को ही।

नमूना कोड

गलत

 def send_welcome_email(email_address, environment): if ENVIRONMENT_NAME == "production": print(f"Sending welcome email to {email_address} from Bob Builder <[email protected]>") else: print("Emails are sent only on production") send_welcome_email("[email protected]", "development") # Emails are sent only on production send_welcome_email("[email protected]", "production") # Sending welcome email to [email protected] from Bob Builder <[email protected]>

सही

 class ProductionEnvironment: FROM_EMAIL = "Bob Builder <[email protected]>" class DevelopmentEnvironment: FROM_EMAIL = "Bob Builder Development <[email protected]>" # We can unit test environments # and even implement different sending mechanisms def send_welcome_email(email_address, environment): print(f"Sending welcome email to {email_address} from {environment.FROM_EMAIL}") # We can delegate into a fake sender (and possible logger) # and unit test it send_welcome_email("[email protected]", DevelopmentEnvironment()) # Sending welcome email to [email protected] from Bob Builder Development <[email protected]> send_welcome_email("[email protected]", ProductionEnvironment()) # Sending welcome email to [email protected] from Bob Builder <[email protected]>

खोज

  • [एक्स] मैनुअल

यह एक डिजाइन गंध है।

हमें खाली विकास/उत्पादन विन्यास बनाने और उन्हें अनुकूलन योग्य बहुरूपी वस्तुओं के साथ सौंपने की आवश्यकता है।

टैग

  • युग्मन

निष्कर्ष

अनुपयुक्त सशर्त जोड़ने से बचें।

व्यावसायिक नियम सौंपते हुए कॉन्फ़िगरेशन बनाएं।

अमूर्त, प्रोटोकॉल और इंटरफेस का प्रयोग करें, कठिन पदानुक्रमों से बचें।

संबंधों

कोड गंध 56 - प्रीप्रोसेसर

और जानकारी

क्रेडिट

Unsplash . पर बर्मिंघम संग्रहालय ट्रस्ट द्वारा फोटो

यह ट्वीट @ Jan Giacomelli . से प्रेरित था

ट्विटर


जटिलता तकनीकी अपरिपक्वता का प्रतीक है। उपयोग की सादगी एक अच्छी तरह से डिजाइन उत्पाद का वास्तविक संकेत है चाहे वह एटीएम हो या पैट्रियट मिसाइल।

डेनियल टी. लिंग

सॉफ्टवेयर इंजीनियरिंग महान उद्धरण


कोड गंध 107 - चर पुन: उपयोग

चर का पुन: उपयोग करने से दायरे और सीमाओं का पालन करना कठिन हो जाता है

TL; DR: अलग-अलग उद्देश्यों के लिए एक ही चर को न पढ़ें और न लिखें

समस्या

  • पठनीयता
  • छिपी हुई समस्याएं

समाधान

  1. चर का पुन: उपयोग न करें
  2. स्कोप को अलग करने की विधि निकालें

संदर्भ

स्क्रिप्ट की प्रोग्रामिंग करते समय वेरिएबल्स का पुन: उपयोग करना आम बात है।

इससे भ्रम होता है और डिबगिंग कठिन हो जाती है।

हमें जितना हो सके इसका दायरा कम करना चाहिए।

नमूना कोड

गलत

 // print line total double total = item.getPrice() * item.getQuantity(); System.out.println("Line total: " + total ); // print amount total total = order.getTotal() - order.getDiscount(); System.out.println( "Amount due: " + total ); // variable is reused

सही

 function printLineTotal() { double total = item.getPrice() * item.getQuantity(); System.out.println("Line total: " + total ); } function printAmountTotal() { double total = order.getTotal() - order.getDiscount(); System.out.println( "Amount due: " + total ); }

खोज

  • [] स्वचालित

चर परिभाषा और उपयोग खोजने के लिए लिंटर पार्स ट्री का उपयोग कर सकते हैं।

टैग

  • पठनीयता

निष्कर्ष

परिवर्तनीय नामों का पुन: उपयोग करने से बचें। अधिक विशिष्ट और भिन्न नामों का प्रयोग करें।

संबंधों

कोड गंध 03 - कार्य बहुत लंबे हैं

और जानकारी

002 रिफैक्टरिंग - निकालने की विधि

क्रेडिट

Unsplash . पर सिगमंड द्वारा फोटो


सामान्यता से पहले सादगी, पुन: उपयोग से पहले उपयोग करें।

केवलिन हेनी

सॉफ्टवेयर इंजीनियरिंग महान उद्धरण


कोड गंध 108 - फ्लोट अभिकथन

दो फ्लोट नंबरों को एक ही मान लेना एक बहुत ही कठिन समस्या है

TL; DR: फ़्लोट्स की तुलना न करें

समस्या

  • गलत परीक्षा परिणाम
  • नाजुक परीक्षण
  • तेजी से विफल सिद्धांत उल्लंघन

समाधान

  1. जब तक आपको वास्तविक प्रदर्शन संबंधी चिंताएं न हों तब तक फ़्लोट से बचें
  2. मनमाने ढंग से सटीक संख्याओं का प्रयोग करें
  3. यदि आपको फ्लोट की तुलना सहिष्णुता के साथ तुलना करने की आवश्यकता है।

संदर्भ

फ्लोट नंबरों की तुलना करना एक पुरानी कंप्यूटर विज्ञान समस्या है।

सामान्य समाधान थ्रेशोल्ड तुलनाओं का उपयोग करना है।

हम अनुशंसा करते हैं कि फ़्लोट से बिल्कुल भी बचें और अनंत सटीक संख्याओं का उपयोग करने का प्रयास करें।

नमूना कोड

गलत

 Assert.assertEquals(0.0012f, 0.0012f); // Deprecated Assert.assertTrue(0.0012f == 0.0012f); // Not JUnit - Smell

सही

 Assert.assertEquals(0.0012f, 0.0014f, 0.0002); // true Assert.assertEquals(0.0012f, 0.0014f, 0.0001); // false // last parameter is the delta threshold Assert.assertEquals(12 / 10000, 12 / 10000); // true Assert.assertEquals(12 / 10000, 14 / 10000); // false

खोज

  • [] स्वचालित

फ्लोट्स की जांच से बचने के लिए हम अपने परीक्षण ढांचे पर एक चेक con assertEquals() जोड़ सकते हैं।

टैग

  • टेस्ट गंध

निष्कर्ष

हमें हमेशा फ्लोट्स की तुलना करने से बचना चाहिए।

संबंधों

कोड गंध 71 - दशमलव के रूप में प्रच्छन्न जादू तैरता है

और जानकारी

क्रेडिट

Unsplash . पर मीका बॉमिस्टर द्वारा फोटो


भगवान ने प्राकृतिक संख्याएं बनाईं; बाकी सब आदमी का काम है।

लियोपोल्ड क्रोनकर

सॉफ्टवेयर इंजीनियरिंग महान उद्धरण


कोड गंध 109 - स्वचालित गुण

यदि आप 4 कोड गंधों को मिलाते हैं तो क्या होता है?

टीएल; डीआर: गेटर्स से बचें, सेटर्स से बचें, मेटाप्रोग्रामिंग से बचें। व्यवहार के बारे में सोचो।

समस्या

समाधान

  1. स्वचालित सेटर्स और गेटर्स निकालें

संदर्भ

सेटर्स और गेटर्स एक खराब उद्योग प्रथा है।

कई आईडीई इस कोड गंध का पक्ष लेते हैं।

कुछ भाषाएं एनीमिक मॉडल और डीटीओ बनाने के लिए स्पष्ट समर्थन प्रदान करती हैं।

नमूना कोड

गलत

 class Person { public string name { get; set; } }

सही

 class Person { private string name public Person(string personName) { name = personName; //imutable //no getters, no setters } //... more protocol, probably accessing private variable name }

खोज

  • [] स्वचालित

यह एक भाषा विशेषता है।

हमें अपरिपक्व भाषाओं से बचना चाहिए या उनकी सबसे खराब प्रथाओं को मना करना चाहिए।

टैग

  • कैप्सूलीकरण

निष्कर्ष

हमें अपनी संपत्तियों को उजागर करने से पहले सावधानी से सोचने की जरूरत है।

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

संबंधों

कोड गंध 28 - सेटर्स

कोड गंध 68 - गेटर्स

कोड गंध 70 - एनीमिक मॉडल जेनरेटर

कोड गंध 40 - डीटीओ

कोड गंध 01 - एनीमिक मॉडल

और जानकारी

क्रेडिट

Unsplash . पर कोनी द्वारा फोटो


एक तंग समय सीमा के तहत काम करने और फिर भी सफाई के लिए समय निकालने से ज्यादा कठिन कुछ नहीं है।

केंट बेकी

सॉफ्टवेयर इंजीनियरिंग महान उद्धरण


कोड गंध 110 - डिफ़ॉल्ट के साथ स्विच करता है

डिफ़ॉल्ट का अर्थ है 'वह सब कुछ जो हम अभी तक नहीं जानते'। हम भविष्य की भविष्यवाणी नहीं कर सकते।

TL; DR: अपने मामलों में एक डिफ़ॉल्ट खंड न जोड़ें। इसे अपवाद के लिए बदलें। स्पष्टवादी बनें।

समस्या

समाधान

  1. अगर और मामलों को बहुरूपता से बदलें
  2. डिफ़ॉल्ट कोड को अपवाद में बदलें

संदर्भ

मामलों का उपयोग करते समय, हम आमतौर पर एक डिफ़ॉल्ट मामला जोड़ते हैं ताकि यह विफल न हो।

बिना सबूत के निर्णय लेने से असफल होना हमेशा बेहतर होता है।

चूंकि केस और स्विच भी एक गंध हैं, इसलिए हम उनसे बच सकते हैं।

नमूना कोड

गलत

 switch (value) { case value1: // if value1 matches the following will be executed.. doSomething(); break; case value2: // if value2 matches the following will be executed.. doSomethingElse(); break; default: // if value does not presently match the above values // or future values // the following will be executed doSomethingSpecial(); break; }

सही

 switch (value) { case value1: // if value1 matches the following will be executed.. doSomething(); break; case value2: // if value2 matches the following will be executed.. doSomethingElse(); break; case value3: case value4: // We currently know these options exist doSomethingSpecial(); break; default: // if value does not match the above values we need to take a decision throw new Exception('Unexpected case ' + value + ' we need to consider it'); break; }

खोज

  • [x] अर्ध स्वचालित

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

टैग

  • तेजी से विफल

निष्कर्ष

मजबूत कोड लिखने का मतलब यह नहीं है कि हमें सबूत के बिना निर्णय लेने की जरूरत है।

संबंधों

कोड गंध 36 - स्विच/केस/elseif/else/if कथन

और जानकारी

क्रेडिट

Unsplash . पर जोशुआ वोरोनीकी द्वारा फोटो


किसी सुविधा को जोड़ने की लागत केवल उसे कोड करने में लगने वाला समय नहीं है। लागत में भविष्य के विस्तार में बाधा भी शामिल है। चाल उन विशेषताओं को चुनना है जो एक दूसरे से नहीं लड़ती हैं।

जॉन कार्मैक

सॉफ्टवेयर इंजीनियरिंग महान उद्धरण



और अभी के लिए बस इतना ही…

अगला लेख 5 और कोड गंधों की व्याख्या करेगा!