मैजिक स्ट्रिंग्स / नंबरों का उपयोग [बंद]


31

यह कुछ हद तक विवादास्पद विषय है, और मुझे लगता है कि प्रोग्रामर के रूप में कई राय हैं। लेकिन इसके लिए, मैं जानना चाहता हूं कि व्यवसाय में सामान्य प्रथाएं क्या हैं (या आपके कार्य स्थानों में)।

मेरे कार्य स्थान में हमारे पास एक सख्त कोडिंग दिशानिर्देश हैं। इसका एक भाग जादू के तार / संख्या के लिए समर्पित है। यह बताता है (C # के लिए):

प्रतीकात्मक स्थिरांक को परिभाषित करने के अलावा, अपने कोड में शाब्दिक मानों का, या तो संख्यात्मक या तार का उपयोग न करें। स्थिरांक को परिभाषित करने के लिए निम्नलिखित पैटर्न का उपयोग करें:

public class Whatever  
{  
   public static readonly Color PapayaWhip = new Color(0xFFEFD5);  
   public const int MaxNumberOfWheels = 18;  
}

अपवाद हैं: मान 0, 1 और अशक्त लगभग हमेशा सुरक्षित रूप से उपयोग किए जा सकते हैं। बहुत बार मान 2 और -1 ठीक भी होते हैं। लॉगिंग या ट्रेसिंग के लिए इच्छित स्ट्रिंग्स को इस नियम से छूट दी गई है। साहित्य की अनुमति तब दी जाती है जब उनका अर्थ संदर्भ से स्पष्ट होता है, न कि भविष्य में होने वाले परिवर्तनों के अधीन।

mean = (a + b) / 2; // okay  
WaitMilliseconds(waitTimeInSeconds * 1000); // clear enough

एक आदर्श स्थिति जब कोड की पठनीयता / स्थिरता पर प्रभाव दिखाने वाले कुछ आधिकारिक शोध पत्र होंगे:

  • मैजिक नंबर / स्ट्रिंग्स सभी जगह हैं
  • मैजिक स्ट्रिंग्स / नंबरों को लगातार घोषणाओं द्वारा प्रतिस्थापित किया जाता है (या कवरेज के विभिन्न डिग्री में) - और कृपया "यथोचित" का उपयोग करने के लिए मुझ पर चिल्लाओ मत, मुझे पता है कि हर कोई अलग विचार रखता है कि "यथोचित" क्या है
  • मैजिक स्ट्रिंग्स / नंबरों को अधिकता से और उन जगहों पर रखा जाता है जहां उन्हें नहीं होना पड़ेगा (नीचे मेरा उदाहरण देखें)

मैं यह करना चाहता हूं कि जब मेरे एक कोलेजियम के साथ बहस हो रही हो, तो कुछ वैज्ञानिक आधार वाली दलीलें दी जाए, जो इस प्रकार बताए जा रहे हैं:

private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;

एक और उदाहरण होगा (और यह एक जावास्क्रिप्ट में है):

var someNumericDisplay = new NumericDisplay("#Div_ID_Here");

क्या आप अपनी आईडी फ़ाइल के ऊपर DOM ID चिपकाते हैं अगर उस ID का उपयोग केवल 1 स्थान पर किया जाता है?

मैंने निम्नलिखित विषयों को पढ़ा है:
StackExchange
StackOverflow
बाइट्स आईटी समुदाय में
और भी कई लेख हैं, और इन्हें पढ़ने के बाद कुछ पैटर्न उभर कर आते हैं।

तो मेरा सवाल यह होना चाहिए कि हमारे कोड में मैजिक स्ट्रिंग्स और संख्याओं का उपयोग किया जाए? मैं विशेष रूप से विशेषज्ञ उत्तरों की तलाश में हूं जो यदि संभव हो तो संदर्भों द्वारा समर्थित हैं।


2
एक जादू चर एक ऐसा चर है जो एक अर्थ रखता है जो इसकी सामग्री से परिलक्षित नहीं होता है। पूर्णांक मान '10' संख्या 10 का अर्थ दर्शाता है, इसलिए इसे स्थिर बनाने की कोई आवश्यकता नहीं है। वही अंतरिक्ष और अर्धविराम के लिए जाता है। दूसरी ओर यदि आपके पास '%% ?? %%' का मान है और यह कुछ कस्टम सीमांकक है, तो यह है कि एचएएस को स्थिरांक के रूप में रखा जाना चाहिए क्योंकि इसकी सामग्री इस तथ्य को प्रतिबिंबित नहीं करती है कि यह एक सीमांकक है।
जीरो वेनवेल

23
NumberTen = 10यह व्यर्थ है क्योंकि संख्या 10 को फिर से परिभाषित नहीं किया जाएगा। MaxRetryCount = 10यह एक बिंदु है जिसे हम अधिकतम रिट्री काउंट बदलना चाहते हैं। private const char SemiColon = ';'; बेवकूफ। private const char LineTerminator = ';'; होशियार।
माइक

1
वास्तविक प्रश्न स्पष्ट नहीं है।
ट्यूलेंस कोरडोवा

जवाबों:


89

... जब मेरे एक कोलेजियम के साथ बहस हो रही है, जो लगातार घोषणा करने की बात कर रहा है जैसे:

private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;

आपको अपने सहकर्मी के साथ जो तर्क करने की ज़रूरत है, वह शाब्दिक स्थान के नामकरण के बारे में नहीं है, Spaceलेकिन उनके स्थिरांक के लिए उनके नाम का खराब विकल्प है।

मान लीजिए कि आपके कोड का काम रिकॉर्ड की एक धारा को पार्स करना है, जिसमें अर्धविराम ( a;b;c) द्वारा अलग किए गए फ़ील्ड हैं और वे स्वयं रिक्त स्थान ( a;b;c d;e;f) द्वारा अलग किए गए हैं । अगर किसी ने भी आपकी कल्पना को लिखा है तो आपको अब से एक महीने पहले कॉल करता है और कहता है, "हमसे गलती हुई थी, रिकॉर्ड में फ़ील्ड्स को पाइप प्रतीकों ( a|b|c d|e|f) से अलग किया जाता है ," आप क्या करते हैं?

मान के रूप में नाम योजना के तहत आपके सहकर्मी पसंद करते हैं, आपको शाब्दिक मूल्य ( SemiColon = '|') को बदलना होगा और उस कोड के साथ रहना SemiColonहोगा जो उस चीज़ के लिए उपयोग करना जारी रखता है जो वास्तव में अर्धविराम नहीं है। इससे कोड समीक्षाओं में नकारात्मक टिप्पणियां आएंगी । कि कम हो जाते हैं के लिए, आप करने के लिए शाब्दिक के नाम को बदल सकता है PipeSymbolऔर के माध्यम से जाने के लिए और के हर घटना को बदलने SemiColonके लिए PipeSymbol। उस दर ';'पर, आपने पहले स्थान पर केवल शाब्दिक अर्धविराम ( ) का उपयोग किया होगा, क्योंकि आपको इसके प्रत्येक उपयोग का व्यक्तिगत रूप से मूल्यांकन करना होगा और आप समान परिवर्तन कर रहे होंगे।

स्थिरांक के लिए पहचानकर्ताओं को यह बताने की आवश्यकता है कि मूल्य क्या करता है , न कि मूल्य क्या है , और यही आपके सहयोगी ने मातम में एक मोड़ बना दिया है। ऊपर वर्णित फ़ील्ड-विभाजन एप्लिकेशन में, अर्धविराम का उद्देश्य एक फ़ील्ड विभाजक है, और स्थिरांक का नाम निम्नानुसार होना चाहिए:

private const char FieldSeparator = ';';    // Will become '|' a month from now
private const char RecordSeparator = ' ';
private const int MaxFieldsPerRecord = 10;

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


मैं पूरी तरह सहमत हूँ। कुछ दशकों पहले मैंने एक परियोजना पर काम किया था, जहाँ संदेश खंडों में भेजे गए थे, जिनमें से प्रत्येक में 8 सामान्य रजिस्टर का उपयोग किया गया था। किसी ने #define one 1 #define two 2 आदि की घोषणा की थी (या जो कुछ भी यूके पोस्ट ऑफिस कोरल में था, पसंद की भाषा)। उच्च से शब्द आया था कि भविष्य में लंबाई क्षेत्र बाइट्स की संख्या होगी, खंड नहीं, इसलिए स्पष्ट रूप से कोड को #define one 8 #define two 16 आदि में बदल दिया गया था
मग

3
के रूप में मूर्खतापूर्ण के रूप में नाम जैसे अर्धविराम या पाइपस्मॉलबोल, एक स्क्रिप्ट का उपयोग करके एक दूसरे को बदलना हर प्रभावित ;को बदलने की तुलना में बहुत आसान होगा |
ब्रैंडिन

उस मामले के बारे में क्या है जहां किसी दिए गए स्ट्रिंग शाब्दिक का उपयोग किसी फ़ाइल में कई बार किया जाता है, लेकिन इसका उसके मूल्य के अलावा कोई अर्थ नहीं है? उदाहरण के लिए, यदि आप परीक्षण कर रहे हैं कि आप 20 भिन्न परिदृश्यों में एक मानचित्र में एक निश्चित कुंजी प्राप्त कर सकते हैं, तो क्या मुझे एक निरंतरता को परिभाषित करना चाहिए ?: public static final String MY_KEY_NAME = "MyKeyName"
जॉर्डन मैकक्वीन

1
@JordanMcQueen नंगे शाब्दिक का उपयोग करने के लिए बनाया जाने वाला एक मामला है (और केवल अगर) तो हर एक को एक बार उपयोग किया जाता है और कहीं और ज़रूरत नहीं होती है। यदि यह एक परिदृश्य किया जा रहा है कोड की तरह कुछ है कि एक अलग फ़ाइल स्वरूप प्रोसेस करता है, प्रत्येक प्रारूप का अपना निरंतर (जैसे, परिभाषित करना चाहिए CSV_RECORD_SEPARATOR, TSV_RECORD_SEPARATOR, आदि)।
Blrfl

8

अर्धविराम को स्थिरांक के रूप में परिभाषित करना निरर्थक है, क्योंकि अर्धविराम पहले से ही निरंतर है । यह कभी बदलने वाला नहीं है।

यह एक दिन की तरह नहीं है कि कोई व्यक्ति "शब्दावली के परिवर्तन, + अब नया अर्धविराम है " की घोषणा करेगा , और आपका सहकर्मी केवल निरंतर को अपडेट करने के लिए खुशी से भाग जाएगा (वे मुझ पर हँसे - अब उन्हें देखें)।

इसमें एक संगति की बात भी है। मैं इस बात की गारंटी देता हूं कि उनका NumberTenनिरंतर उपयोग हर किसी के द्वारा नहीं किया जाएगा (अधिकांश कोडर उनके दिमाग से बाहर नहीं हैं), इसलिए यह वैसे भी जो भी उद्देश्य की उम्मीद थी, वह पूरा नहीं करेगा। जब सर्वनाश आता है और "दस" विश्व स्तर पर 9 तक पहुंच जाता है, तो अपडेट करना निरंतर चाल नहीं चलेगा, क्योंकि यह अभी भी आपको 10अपने कोड में शाब्दिक एस के ढेर के साथ छोड़ देगा , इसलिए अब यह प्रणाली दायरे के भीतर भी पूरी तरह से अप्रत्याशित हो जाती है। एक क्रांतिकारी धारणा है कि "दस" का अर्थ है "9"।

सभी सेटिंग्स को कॉन्स्टेंस के रूप में संग्रहीत करना कुछ ऐसा है जिसके बारे में मेरे पास दूसरे विचार होंगे। किसी को भी इसे हल्के में नहीं करना चाहिए।

इस प्रकार के उपयोग के कौन से उदाहरण हमने अब तक एकत्रित किए हैं? लाइन टर्मिनेटर ... अधिकतम रिट्री गिनती ... पहियों की अधिकतम संख्या ... क्या हम सकारात्मक हैं ये कभी नहीं बदलेंगे?

लागत यह है कि डिफ़ॉल्ट सेटिंग्स को बदलने के लिए एक आवेदन को फिर से जमा करने की आवश्यकता होती है, और कुछ मामलों में, यहां तक ​​कि इसकी निर्भरता (जैसे कि संकेंद्रन का मान मान संकलन के दौरान हार्ड-कोडित हो सकता है)।

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


4
"यह कभी बदलने वाला नहीं है।" मैं सोचता था कि एपोस्ट्रोफ (हमेशा एएससीआईआई मूल्य 39 से बंधा हुआ) के बारे में। कुछ पुराने ऐप एपोस्ट्रोफ को कर्ल करते थे। लेकिन अब आधुनिक ऐप्स पुराने ऐप के साथ संगत एपोस्ट्रोपी के रूप में उस एएससीआईआई मूल्य का इलाज करते हैं, और इसके बजाय लोग अक्सर कर्ल किए गए निशान के लिए एक अलग ग्लिफ़ दिखाने के साथ संगत ऐप के लिए (बाएं एकल उद्धरण, यूनिकोड 8217 ) का उपयोग करते हैं। यह होने के नाते कि यूरोप कॉमा का उपयोग करता है जिस तरह से अमेरिकी एक दशमलव बिंदु के रूप में अवधि का उपयोग करते हैं, मैं खुद को "कभी नहीं ..." घोषित करने में थोड़ा संकोच करता हूं।
TOOGAM

@TOOGAM ठीक है, आपका उदाहरण एक DecimalPointस्थिर होने को सही ठहराता है - लेकिन स्थिर Commaया Periodस्थिर नहीं । यह काफी अंतर है: पूर्व एक फ़ंक्शन , एक भूमिका या मूल्य के एक उद्देश्य को दर्शाता है । "अर्धविराम" या "अल्पविराम" उस श्रेणी में नहीं आते हैं।
कोनराड मोरावस्की

यह दशमलव बिंदु उदाहरण के लिए सही है। हालाँकि, एपोस्ट्रोफ उदाहरण अल्पविराम (या अर्ध-उपनिवेश) के समान (या समरूप) श्रेणी का प्रतीत होता है।
TOOGAM

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

5
private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;

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

private const char StatementTerminator = ';';
private const char Delimiter = ' ';
private const int  BalanceInquiryCode = 10;

"मैजिक" संख्याएं और तार निरंतर हैं जो उनके तात्कालिक, शाब्दिक मूल्य से परे अर्थ रखते हैं। यदि स्थिरांक 10का अर्थ "दस चीजों" से परे है (एक विशिष्ट ऑपरेशन या त्रुटि स्थिति के लिए एक कोड के रूप में कहें), कि जब यह "जादू" हो जाता है और एक प्रतीकात्मक स्थिरांक द्वारा प्रतिस्थापित किया जाना चाहिए जो उस सार अर्थ का वर्णन करता है।

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


3

इसके बारे में कुछ भी विवादास्पद नहीं होना चाहिए। बिंदु जादू की संख्या का उपयोग करने के लिए तार के बारे में नहीं है या नहीं, बिंदु पठनीय कोड है।
के बीच अंतर पर विचार करें: if(request.StatusCode == 1)और if(request.HasSucceeded)। इस मामले में, मैं तर्क दूंगा कि उत्तरार्द्ध कहीं अधिक पठनीय है, लेकिन इसका मतलब यह नहीं है कि आपके पास कभी कोड नहीं हो सकता है int MaxNumberOfWheels = 18

पुनश्च: यही कारण है कि मैं बिल्कुल दिशानिर्देशों से नफरत करता हूं। डेवलपर्स को इस तरह से निर्णय लेने में सक्षम होने के लिए पर्याप्त परिपक्व होना चाहिए; वे इसे भगवान द्वारा गठित पाठ के एक टुकड़े पर नहीं छोड़ना चाहिए जो जानता है।


13
ड्राइवरों को परिपक्व होना चाहिए कि वे सड़क के किस तरफ निर्णय लेने में सक्षम हों;)
कोनराड मोरावस्की

2
एक निर्णय कॉल का परिणाम परिपक्व डेवलपर्स के बीच भी भिन्न हो सकता है, इसलिए यहां तक ​​कि मनमाने ढंग से कोडिंग दिशानिर्देश स्थिरता के माध्यम से पठनीयता में सुधार करने के लिए हैं। यह इस तथ्य से असंबंधित है कि एक निरंतर नंबरटैन बनाने से कोई मतलब नहीं है।
माइक पार्टरिज

1
मैं यह आग्रह नहीं करूंगा कि उन्हें औपचारिक, मुद्रांकित आदि होना चाहिए, वे अनौपचारिक हो सकते हैं, लेकिन उन पर सहमति होनी चाहिए, और यह पहले से ही निर्णय की व्यक्तिगत परिपक्वता का उपयोग करने से परे है। लेकिन आपने अपनी टिप्पणी अब हटा दी है स्टीफन :)
कोनराड मोरव्स्की

1
@StefanBilliet - बिल्कुल नहीं। मेरा कहना है कि स्थिरता के माध्यम से पठनीयता में सुधार होता है। यहाँ समस्या स्वयं कोडिंग दिशानिर्देश नहीं है, बल्कि गलतफहमी के माध्यम से चरम सीमा तक ले जाया गया दिशानिर्देश है।
माइक पार्टरिज

@ माइकपार्ट्रिज शायद मुझे विस्तृत होना चाहिए; मैंने जो कोडिंग दिशा-निर्देश देखे हैं, वे सामान्य नियम-पुस्तिका के चलन में अधिक हैं कि कैसे किसी को लगा कि सॉफ्टवेयर को लिखा जाना चाहिए, बल्कि आपके और कोनराड जैसे समझौतों के बारे में शायद सोच रहे हैं :-)
स्टीफन बिलिएट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.