यह गंध करता है क्योंकि ऐसे कई उदाहरण हैं जहां इसे संपादित या सुधार किया जा सकता है।
इनमें से अधिकतर गंध कुछ गलत होने का संकेत मात्र हैं। वे अनिवार्य रूप से निश्चित नहीं हैं ... (हालांकि आपको इसे देखना चाहिए।)
चलो जारी रखते है...
उत्पादन परिवेश के लिए IFs जाँच न जोड़ें।
TL; DR: उत्पादन से संबंधित शर्तों को जोड़ने से बचें
कभी-कभी, हमें विकास और उत्पादन में अलग-अलग व्यवहार बनाने की आवश्यकता होती है।
उदाहरण के लिए पासवर्ड की ताकत।
इस मामले में, हमें पर्यावरण को ताकत की रणनीति के साथ कॉन्फ़िगर करने और रणनीति का परीक्षण करने की आवश्यकता है, न कि पर्यावरण को ही।
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]>
यह एक डिजाइन गंध है।
हमें खाली विकास/उत्पादन विन्यास बनाने और उन्हें अनुकूलन योग्य बहुरूपी वस्तुओं के साथ सौंपने की आवश्यकता है।
अनुपयुक्त सशर्त जोड़ने से बचें।
व्यावसायिक नियम सौंपते हुए कॉन्फ़िगरेशन बनाएं।
अमूर्त, प्रोटोकॉल और इंटरफेस का प्रयोग करें, कठिन पदानुक्रमों से बचें।
Unsplash . पर बर्मिंघम संग्रहालय ट्रस्ट द्वारा फोटो
यह ट्वीट @ Jan Giacomelli . से प्रेरित था
जटिलता तकनीकी अपरिपक्वता का प्रतीक है। उपयोग की सादगी एक अच्छी तरह से डिजाइन उत्पाद का वास्तविक संकेत है चाहे वह एटीएम हो या पैट्रियट मिसाइल।
डेनियल टी. लिंग
सॉफ्टवेयर इंजीनियरिंग महान उद्धरण
चर का पुन: उपयोग करने से दायरे और सीमाओं का पालन करना कठिन हो जाता है
TL; DR: अलग-अलग उद्देश्यों के लिए एक ही चर को न पढ़ें और न लिखें
स्क्रिप्ट की प्रोग्रामिंग करते समय वेरिएबल्स का पुन: उपयोग करना आम बात है।
इससे भ्रम होता है और डिबगिंग कठिन हो जाती है।
हमें जितना हो सके इसका दायरा कम करना चाहिए।
// 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 . पर सिगमंड द्वारा फोटो
सामान्यता से पहले सादगी, पुन: उपयोग से पहले उपयोग करें।
केवलिन हेनी
सॉफ्टवेयर इंजीनियरिंग महान उद्धरण
दो फ्लोट नंबरों को एक ही मान लेना एक बहुत ही कठिन समस्या है
TL; DR: फ़्लोट्स की तुलना न करें
फ्लोट नंबरों की तुलना करना एक पुरानी कंप्यूटर विज्ञान समस्या है।
सामान्य समाधान थ्रेशोल्ड तुलनाओं का उपयोग करना है।
हम अनुशंसा करते हैं कि फ़्लोट से बिल्कुल भी बचें और अनंत सटीक संख्याओं का उपयोग करने का प्रयास करें।
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 . पर मीका बॉमिस्टर द्वारा फोटो
भगवान ने प्राकृतिक संख्याएं बनाईं; बाकी सब आदमी का काम है।
लियोपोल्ड क्रोनकर
सॉफ्टवेयर इंजीनियरिंग महान उद्धरण
यदि आप 4 कोड गंधों को मिलाते हैं तो क्या होता है?
टीएल; डीआर: गेटर्स से बचें, सेटर्स से बचें, मेटाप्रोग्रामिंग से बचें। व्यवहार के बारे में सोचो।
सेटर्स और गेटर्स एक खराब उद्योग प्रथा है।
कई आईडीई इस कोड गंध का पक्ष लेते हैं।
कुछ भाषाएं एनीमिक मॉडल और डीटीओ बनाने के लिए स्पष्ट समर्थन प्रदान करती हैं।
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 }
यह एक भाषा विशेषता है।
हमें अपरिपक्व भाषाओं से बचना चाहिए या उनकी सबसे खराब प्रथाओं को मना करना चाहिए।
हमें अपनी संपत्तियों को उजागर करने से पहले सावधानी से सोचने की जरूरत है।
पहला कदम गुणों के बारे में सोचना बंद करना और पूरी तरह से व्यवहार पर ध्यान केंद्रित करना है।
कोड गंध 70 - एनीमिक मॉडल जेनरेटर
Unsplash . पर कोनी द्वारा फोटो
एक तंग समय सीमा के तहत काम करने और फिर भी सफाई के लिए समय निकालने से ज्यादा कठिन कुछ नहीं है।
केंट बेकी
सॉफ्टवेयर इंजीनियरिंग महान उद्धरण
डिफ़ॉल्ट का अर्थ है 'वह सब कुछ जो हम अभी तक नहीं जानते'। हम भविष्य की भविष्यवाणी नहीं कर सकते।
TL; DR: अपने मामलों में एक डिफ़ॉल्ट खंड न जोड़ें। इसे अपवाद के लिए बदलें। स्पष्टवादी बनें।
मामलों का उपयोग करते समय, हम आमतौर पर एक डिफ़ॉल्ट मामला जोड़ते हैं ताकि यह विफल न हो।
बिना सबूत के निर्णय लेने से असफल होना हमेशा बेहतर होता है।
चूंकि केस और स्विच भी एक गंध हैं, इसलिए हम उनसे बच सकते हैं।
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; }
जब तक कोई अपवाद न हो, हम अपने लिंटर्स को डिफ़ॉल्ट उपयोगों पर हमें चेतावनी देने के लिए कह सकते हैं।
मजबूत कोड लिखने का मतलब यह नहीं है कि हमें सबूत के बिना निर्णय लेने की जरूरत है।
कोड गंध 36 - स्विच/केस/elseif/else/if कथन
Unsplash . पर जोशुआ वोरोनीकी द्वारा फोटो
किसी सुविधा को जोड़ने की लागत केवल उसे कोड करने में लगने वाला समय नहीं है। लागत में भविष्य के विस्तार में बाधा भी शामिल है। चाल उन विशेषताओं को चुनना है जो एक दूसरे से नहीं लड़ती हैं।
जॉन कार्मैक
सॉफ्टवेयर इंजीनियरिंग महान उद्धरण
और अभी के लिए बस इतना ही…
अगला लेख 5 और कोड गंधों की व्याख्या करेगा!