क्या हमारे अनुप्रयोगों में मूल्यों को फिर से परिभाषित करना एक अच्छा विचार है? या क्या इस प्रकार के मूल्यों को गतिशील रूप से कॉल करने के लिए हमेशा सही बात है, अगर उन्हें बदलने की आवश्यकता है?
pi
सकते हैं कि कब मूल्य बदल सकता है ...
क्या हमारे अनुप्रयोगों में मूल्यों को फिर से परिभाषित करना एक अच्छा विचार है? या क्या इस प्रकार के मूल्यों को गतिशील रूप से कॉल करने के लिए हमेशा सही बात है, अगर उन्हें बदलने की आवश्यकता है?
pi
सकते हैं कि कब मूल्य बदल सकता है ...
जवाबों:
हां, लेकिन इसे स्पष्ट करें ।
करना:
मत करो:
diameter = 2 * radius
या diameter = RADIUS_TO_DIAMETER_FACTOR * radius
? वास्तव में कोने के मामले हैं जहां एक जादू नंबर बेहतर समाधान हो सकता है।
diameter = radius << 1
? मुझे लगता है कि यह भी हो सकता है diameter = radius << RADIUS_TO_DIAMETER_BITS_TO_SHIFT
।
diameter = radius.toDiameter()
इस प्रश्नोत्तर के बारे में मुझे जो कुछ अजीब लगता है वह यह है कि किसी ने वास्तव में "हार्ड-कोड" को स्पष्ट रूप से परिभाषित करने का प्रयास नहीं किया है या इससे भी महत्वपूर्ण बात यह है कि विकल्प।
tl; डॉ: हाँ, यह है कभी कभी हार्ड कोड मूल्यों के लिए एक अच्छा विचार है, लेकिन वहाँ के रूप में कोई सरल नियम है जब ; यह पूरी तरह से संदर्भ पर निर्भर करता है।
सवाल इसे मूल्यों तक सीमित कर देता है , जिसका मतलब है कि मैं जादू की संख्याओं को लेता हूं , लेकिन वे एक अच्छा विचार है या नहीं इसका जवाब यह है कि वे वास्तव में किसके लिए उपयोग किए जाते हैं!
"हार्ड-कोडित" मूल्यों के कई उदाहरण हैं:
कॉन्फ़िगरेशन मान
जब भी मैं जैसे बयान देखता हूं, मैं उखड़ जाता हूं command.Timeout = 600
। क्यों 600? किसने तय किया? क्या यह समय से पहले खत्म हो गया था, और किसी ने अंतर्निहित प्रदर्शन के मुद्दे को ठीक करने के बजाय हैक के रूप में टाइमआउट उठाया था? या यह वास्तव में प्रसंस्करण समय के लिए कुछ ज्ञात और प्रलेखित अपेक्षा है?
ये मैजिक नंबर या स्थिरांक नहीं होने चाहिए , इन्हें एक विन्यास फाइल या डेटाबेस में एक सार्थक नाम के साथ कहीं बाहर रखा जाना चाहिए, क्योंकि इनका इष्टतम मूल्य काफी हद तक या पूरी तरह से पर्यावरण द्वारा निर्धारित किया जाता है कि एप्लिकेशन चल रहा है।
गणित के सूत्र
सूत्र आमतौर पर बहुत स्थिर होते हैं, जैसे कि अंदर निरंतर मूल्यों की प्रकृति वास्तव में महत्वपूर्ण नहीं है। एक पिरामिड का आयतन (1/3) b * h है। क्या हमें परवाह है कि 1 या 3 कहाँ से आया है? ज़रुरी नहीं। पिछले टिप्पणीकार ने ठीक ही बताया कि diameter = radius * 2
शायद इससे बेहतर है diameter = radius * RADIUS_TO_DIAMETER_CONVERSION_FACTOR
- लेकिन यह एक गलत द्वंद्व है।
इस प्रकार के परिदृश्य के लिए आपको क्या करना चाहिए, एक फ़ंक्शन बना रहा है । मुझे यह जानने की आवश्यकता नहीं है कि आप कैसे सूत्र के साथ आए , लेकिन मुझे अभी भी यह जानने की आवश्यकता है कि इसके लिए क्या है । अगर, ऊपर लिखे किसी भी बकवास के बजाय, मैं लिखता हूं volume = GetVolumeOfPyramid(base, height)
तो अचानक सब कुछ बहुत स्पष्ट हो जाता है, और फ़ंक्शन के अंदर मैजिक नंबर होना पूरी तरह से ठीक है ( return base * height / 3
) क्योंकि यह स्पष्ट है कि वे सूत्र का सिर्फ एक हिस्सा हैं।
यहाँ कुंजी बेशक छोटे और सरल कार्य है। यह 10 तर्कों और गणना की 30 पंक्तियों के साथ कार्यों के लिए काम नहीं करता है। उस स्थिति में फ़ंक्शन कंपोजिशन या स्थिरांक का उपयोग करें।
डोमेन / व्यावसायिक नियम
यह हमेशा ग्रे क्षेत्र होता है क्योंकि यह इस बात पर निर्भर करता है कि वास्तव में मूल्य क्या है। अधिकांश समय, यह इन विशेष जादू की संख्याएं होती हैं जो स्थिरांक में बदलने के लिए उम्मीदवार हैं, क्योंकि इससे प्रोग्राम लॉजिक को जटिल किए बिना प्रोग्राम को समझना आसान हो जाता है। परीक्षण पर विचार if Age < 19
बनाम if Age < LegalDrinkingAge
; आप शायद यह पता लगा सकते हैं कि निरंतर के बिना क्या चल रहा है, लेकिन वर्णनात्मक शीर्षक के साथ यह आसान है।
उदाहरण के लिए, ये कार्य अमूर्तता के लिए भी उम्मीदवार बन सकते हैंfunction isLegalDrinkingAge(age) { return age >= 19 }
। केवल एक चीज यह है कि अक्सर आपका व्यावसायिक तर्क उससे कहीं अधिक जटिल होता है, और प्रत्येक 20-30 मापदंडों के साथ दर्जनों कार्यों को लिखना शुरू करने का कोई मतलब नहीं हो सकता है। यदि वस्तुओं और / या कार्यों के आधार पर स्पष्ट अमूर्तता नहीं है तो स्थिरांक का सहारा लेना ठीक है।
कैविएट, यदि आप कर विभाग के लिए काम कर रहे हैं, तो यह वास्तव में, वास्तव में बोझिल और ईमानदारी से लिखने के लिए व्यर्थ हो जाता है AttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR)
। आप ऐसा नहीं करने जा रहे हैं, आप AttachForm("B-46")
इसलिए जा रहे हैं क्योंकि हर एक डेवलपर जिसने कभी काम किया है या कभी काम करेगा वहाँ पता चल रहा है कि "बी -46" एकल करदाता फाइलिंग ब्ला ब्ला ब्ला के लिए फॉर्म कोड है - फ़ॉर्म कोड स्वयं डोमेन का हिस्सा हैं, वे कभी नहीं बदलते हैं, इसलिए वे वास्तव में जादू नंबर नहीं हैं।
इसलिए आपको व्यवसाय तर्क में संयम से उपयोग करना होगा; मूल रूप से आपको यह समझना होगा कि "जादू नंबर" वास्तव में एक जादू नंबर है या यदि यह डोमेन का एक प्रसिद्ध पहलू है। यदि यह डोमेन है, तो आप इसे नरम-कोड नहीं करते हैं, जब तक कि यह वास्तव में अच्छा मौका न हो, यह बदल जाएगा।
त्रुटि कोड और स्थिति ध्वज
ये कभी भी हार्ड-कोड के लिए ठीक नहीं हैं , क्योंकि कोई भी गरीब कमीना जो कभी भी Previous action failed due to error code 46
आपको बता सकता है। यदि आपकी भाषा इसका समर्थन करती है, तो आपको एक गणना प्रकार का उपयोग करना चाहिए। अन्यथा, आपके पास आमतौर पर एक संपूर्ण फ़ाइल / मॉड्यूल होगा जो किसी विशेष त्रुटि प्रकार के लिए मान्य मानों को निर्दिष्ट करने वाले स्थिरांक से भरा होता है।
कभी भी मुझे return 42
एक त्रुटि हैंडलर में देखने की अनुमति न दें ? कोई बहना नहीं।
मैंने शायद कई परिदृश्यों को छोड़ दिया, लेकिन मुझे लगता है कि उनमें से अधिकांश को शामिल किया गया है।
तो, हाँ, यह कभी-कभी कठोर कोड सामग्री के लिए स्वीकार्य अभ्यास है। बस इसके बारे में आलसी मत बनो; यह सादे पुराने मैला कोड के बजाय एक सचेत निर्णय होना चाहिए।
पहचानकर्ता को एक नंबर पर असाइन करने के विभिन्न कारण हैं।
यह हमें हार्ड-कोडिंग शाब्दिकों के लिए मापदंड प्रदान करता है। उन्हें अपरिवर्तनीय होना चाहिए, टाइप करना मुश्किल नहीं, केवल एक जगह या संदर्भ में, और पहचानने योग्य अर्थ के साथ। उदाहरण के लिए ARRAY_BEGINNING के रूप में 0 को परिभाषित करने का कोई मतलब नहीं है, या ARRAY_INCREMENT के रूप में 1 है।
अन्य उत्तरों के अतिरिक्त। जब संभव हो तार के लिए स्थिरांक का उपयोग करें। बेशक, आप नहीं करना चाहते हैं
const string server_var="server_var";
लेकिन आपके पास होना चाहिए
const string MySelectQuery="select * from mytable;";
(यह मानते हुए कि आपके पास वास्तव में एक क्वेरी है जहां आप एक विशिष्ट तालिका से सभी परिणाम प्राप्त करना चाहते हैं, हमेशा)
इसके अलावा, 0 (आमतौर पर) के अलावा किसी भी संख्या के लिए स्थिरांक का उपयोग करें। यदि आपको 255 के अनुमति बिटमास्क की आवश्यकता है, तो उपयोग न करें
const int 8th_bit=255; //or some other obscure naming scheme that equates to 255.
इसके बजाय उपयोग करें
const int AllowGlobalRead=255;
बेशक, स्थिरांक के साथ, पता है कि कब एन्यूमरेटर्स का उपयोग करना है। उपरोक्त मामला शायद एक में अच्छी तरह से फिट होगा।
typedef enum {init_state=0, parse_state=1, evaluation_state=2, ... }
यह निर्भर करता है कि आप हार्डकोडिंग को क्या मानते हैं। यदि आप किसी भी और सभी हार्डकोड चीजों से बचने की कोशिश करते हैं, तो आप सॉफ्टकोडिंग क्षेत्र में समाप्त होते हैं , और एक ऐसी प्रणाली बनाते हैं जिसे केवल निर्माता ही प्रबंधित कर सकता है (और यह अंतिम हार्डकोड है)
किसी भी उचित ढांचे में बहुत सी चीजें हार्डकोड की जाती हैं और वे काम करती हैं। अर्थात ऐसा कोई तकनीकी कारण नहीं है कि मैं C # एप्लिकेशन (स्टैटिक शून्य मेन) के प्रवेश बिंदु को बदलने में सक्षम न हो पाऊं, लेकिन हार्डकोडिंग जो किसी भी उपयोगकर्ता के लिए कोई समस्या पैदा नहीं करता है (कभी-कभार SO प्रश्न को छोड़कर )
अंगूठे का नियम मैं उपयोग करता हूं कि पूरी व्यवस्था की स्थिति को प्रभावित किए बिना, जो कुछ भी बदल सकता है और बदल सकता है, उसे भ्रमित किया जाना चाहिए।
इसलिए, IMHO, यह मूर्खतापूर्ण है कि वे चीजें जो कभी नहीं बदल रही हैं (pi, गुरुत्वाकर्षण स्थिरांक, एक गणितीय सूत्र में एक स्थिरांक - एक गोले का आयतन)।
इसके अलावा यह मूर्खतापूर्ण नहीं है कि हार्डकोड चीजों या प्रक्रियाओं का आपके सिस्टम पर प्रभाव पड़ेगा, जिन्हें किसी भी उदाहरण में प्रोग्रामिंग की आवश्यकता होगी, अर्थात यह उपयोगकर्ता के लिए गतिशील क्षेत्रों को जोड़ने के लिए अनुमति देने के लिए बेकार है, अगर किसी भी जोड़ा क्षेत्र को रखरखाव डेवलपर की आवश्यकता होगी अंदर जाओ और कुछ स्क्रिप्ट लिखो जो काम करने के लिए उस चीज़ को बनाएगी। इसके अलावा यह बेवकूफ है (और मैंने इसे एंटरप्राइज़ वातावरण में कुछ समय देखा है) कुछ कॉन्फ़िगरेशन टूल बनाने के लिए, इसलिए कुछ भी हार्डकोड नहीं है, फिर भी, आईटी विभाग में केवल डेवलपर्स इसका उपयोग कर सकते हैं, और इसे उपयोग करने के लिए केवल थोड़ा आसान है इसे Visual Studio में करने के लिए।
तो, नीचे की रेखा, चाहे वह चीज़ हार्डकोड हो, दो चरों का एक कार्य है:
क्या हमारे अनुप्रयोगों में मूल्यों को फिर से परिभाषित करना एक अच्छा विचार है?
मैं केवल हार्डकोड मानों को निर्दिष्ट करता हूं यदि मान विनिर्देश में निर्दिष्ट किए गए हैं (विनिर्देश के अंतिम रिलीज पर), उदाहरण के लिए HTTP ओके प्रतिक्रिया हमेशा रहेगी 200
(जब तक कि यह आरएफसी में नहीं बदलता है), इसलिए, आप देखेंगे (मेरे कुछ कोड में) ) स्थिरांक जैसे:
public static final int HTTP_OK = 200;
अन्यथा, मैं गुण फ़ाइल में स्थिरांक संग्रहीत करता हूं।
मेरे द्वारा निर्दिष्ट विनिर्देशों का कारण यह है कि विनिर्देशों में बदलते स्थिरांक को परिवर्तन प्रबंधन की आवश्यकता होती है, जिसमें, हितधारक परिवर्तन की समीक्षा करेंगे और अनुमोदन / अस्वीकृत करेंगे। यह कभी भी रातोंरात नहीं होता है और अनुमोदन के लिए महीनों / वर्षों का समय लेता है। मत भूलो कि कई डेवलपर्स विनिर्देशों (जैसे HTTP) का उपयोग करते हैं इसलिए इसे बदलने का मतलब है लाखों सिस्टम को तोड़ना।
मैंने देखा है कि किसी भी समय आप अपने कोड से डेटा निकाल सकते हैं, इससे सुधार होता है कि क्या बचा है। आप नए रिफ्लेक्टर को सूचित करना शुरू कर देते हैं और अपने कोड के पूरे अनुभागों में सुधार करते हैं।
स्थिरांक निकालने की दिशा में काम करना सिर्फ एक अच्छा विचार है, इसे कुछ बेवकूफी भरा नियम न समझें, इसे बेहतर कोड करने के अवसर के रूप में सोचें।
सबसे बड़ा फायदा यह होगा कि आपको समान कॉन्स्टेंट्स कोड के समूहों में एकमात्र अंतर मिल सकते हैं - उन्हें सरणियों में अमूर्त करने से मुझे कुछ फाइलों को उनके आकार के 90% तक कम करने में मदद मिली है और इस बीच कुछ कॉपी और पेस्ट बग्स को ठीक किया है। ।
डेटा निकालने के लिए मुझे अभी तक एक भी फायदा नहीं हुआ है।
मैंने हाल ही में दो लेट / लॉन्ग पेयर के बीच की दूरी की सही गणना करने के लिए एक MySQL फ़ंक्शन को कोडित किया। आप सिर्फ पाइथागोरस नहीं कर सकते; देशांतर रेखाएं एक साथ करीब आती हैं क्योंकि अक्षांश ध्रुवों की ओर बढ़ता है, इसलिए इसमें थोड़े बालों वाले ट्रिगर्स शामिल होते हैं। बिंदु है, मैं इस बारे में बहुत फटा हुआ था कि क्या मील में पृथ्वी की त्रिज्या का प्रतिनिधित्व करने वाले मूल्य को कठिन-कोड करना है या नहीं।
मैंने यह करना समाप्त कर दिया, भले ही तथ्य यह है कि, लाट / लैंग लाइनें चंद्रमा पर बहुत करीब से एक साथ हैं, कहते हैं। और मेरे कार्य में बृहस्पति पर बिंदुओं के बीच काफी कम दूरी होगी। मुझे लगा कि जिस वेबसाइट पर मैं एक अलौकिक स्थान का निर्माण कर रहा हूँ, उसका अंतर बहुत पतला है।
वैसे यह निर्भर करता है कि आपकी भाषा संकलित है या नहीं। यदि यह संकलित नहीं है, तो यह कोई बड़ी बात नहीं है, आप सिर्फ स्रोत कोड को संपादित करते हैं, भले ही यह गैर प्रोग्रामर के लिए थोड़ा नाजुक हो।
यदि आप संकलित भाषा के साथ प्रोग्रामिंग कर रहे हैं, तो यह स्पष्ट रूप से एक अच्छा विचार नहीं है, क्योंकि यदि चर बदलते हैं, तो आपको फिर से खेलना होगा, जो कि इस चर को समायोजित करना चाहते हैं, तो समय की एक बड़ी बर्बादी है।
आपको अपने चर को गतिशील रूप से बदलने के लिए कुछ स्लाइडर या इंटरफ़ेस बनाने की आवश्यकता नहीं है, लेकिन कम से कम आप जो कर सकते हैं वह एक पाठ फ़ाइल है।
मेरे ओग्रे परियोजना के साथ उदाहरण के लिए, मैं हमेशा कॉन्फिग फाइल का उपयोग कर रहा हूं, एक वैरिएबल लोड करने के लिए जो मैंने एक कॉन्फिगर फाइल में लिखा है।
दो मौके जहां स्थिरांक हैं (कम से कम मेरी राय में) ठीक है:
लगातार जो कुछ और से संबंधित नहीं है; आप उन स्थिरांक को बदल सकते हैं जब भी आप बिना कुछ और बदलने के लिए पसंद करते हैं। उदाहरण: ग्रिड कॉलम की डिफ़ॉल्ट चौड़ाई।
बिल्कुल अपरिवर्तनीय, सटीक, स्पष्ट स्थिरांक, जैसे "प्रति सप्ताह दिनों की संख्या"। एक निरंतर के साथ days = weeks * 7
प्रतिस्थापित 7
करना DAYS_PER_WEEK
शायद ही कोई मूल्य प्रदान करता है।
मैं जोनाथन से पूरी तरह सहमत हूं लेकिन सभी नियमों के अलावा अपवाद हैं ...
"मैजिक नंबर इन द स्पेक: कोड में मैजिक नंबर"
मूल रूप से कहा गया है कि उनके लिए वर्णनात्मक संदर्भ प्राप्त करने के लिए उचित प्रयासों के बाद कल्पना में जो भी जादू की संख्या बनी हुई है, उसे इस तरह के कोड में परिलक्षित किया जाना चाहिए। यदि जादू की संख्या कोड में रहती है, तो उन्हें अलग-थलग करने के लिए हर संभव प्रयास किया जाना चाहिए और उन्हें स्पष्ट रूप से उनके मूल बिंदु से जोड़ा जाना चाहिए।
मैंने कुछ इंटरफेसिंग कॉन्ट्रैक्ट्स का प्रदर्शन किया है, जहाँ डेटाबेस से मैप किए गए मूल्यों के साथ संदेशों को आबाद करना आवश्यक है। ज्यादातर मामलों में मैपिंग एकदम सीधी होती है और जोनाथन की सामान्य गाइड लाइन्स में फिट होती है, लेकिन मुझे ऐसे मामलों का सामना करना पड़ा है जहां लक्ष्य संदेश संरचना बस सादा भयानक थी। 80% से अधिक मूल्यों को संरचना में पारित किया जाना था, जो दूर प्रणाली के विनिर्देश द्वारा लागू किया गया था। इस तथ्य के साथ युग्मित किया गया है कि संदेश संरचना को अभिमानी बनाया गया था कि ऐसे स्थिरांक के एक बहुत को आबाद किया जाना था। ज्यादातर मामलों में वे एक अर्थ या कारण प्रदान नहीं करते हैं, बस कहा गया "यहां एम डाल दें" या "4.10.53.10100.889450.4452 यहां डालें"। मैंने या तो उन सभी के बगल में एक टिप्पणी करने का प्रयास नहीं किया, जिसके परिणामस्वरूप यह परिणाम अपठनीय हो सकता है।
उस ने कहा, जब आप इसके बारे में सोचते हैं ... यह बहुत स्पष्ट है इसे स्पष्ट करने के बारे में ...
यदि आप पृथ्वी के गुरुत्वाकर्षण स्थिरांक के मान को हार्डकोर कर रहे हैं, तो किसी का ध्यान नहीं जा रहा है। यदि आप अपने प्रॉक्सी सर्वर के आईपी पते को हार्डकोड करते हैं, तो आप परेशानी में हैं।
ज्यादातर नहीं, लेकिन मुझे लगता है कि यह ध्यान देने योग्य है कि जब आप हार्ड-कोडित मूल्य की नकल करना शुरू करेंगे तो आपको सबसे अधिक समस्या होगी। यदि आप इसे डुप्लिकेट नहीं करते हैं (उदाहरण के लिए एक बार लागू होने के बाद इसे एक बार उपयोग करें) तो निरंतर का उपयोग करना ठीक नहीं हो सकता है।