वास्तव में "सॉफ्ट कोडिंग" क्या है?


87

में इस लेख एलेक्स Papadimoulis द्वारा, तो आप इस टुकड़ा देख सकते हैं:

private void attachSupplementalDocuments()
{
  if (stateCode == "AZ" || stateCode == "TX") {

    //SR008-04X/I are always required in these states
    attachDocument("SR008-04X");
    attachDocument("SR008-04XI");
  }

  if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

  if (coInsuredCount >= 5  && orgStatusCode != "CORP") {
    //Non-CORP orgs with 5 or more co-ins require AUTHCNS-1A
    attachDocument("AUTHCNS-1A");
  }
}

मैं वास्तव में इस लेख को नहीं समझता।

मैं उद्धृत करता हूं:

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

यह कॉन्फ़िगरेशन फ़ाइल में "500000" निरंतर पूर्णांक, या "AUTHCNS-1A" और अन्य स्ट्रिंग स्थिरांक होने के खिलाफ एक तर्क है।

यह एक बुरा अभ्यास कैसे हो सकता है?

इस स्निपेट में, "500000" एक संख्या नहीं है। उदाहरण के लिए, यह नहीं है:

int doubleMe(int a) { return a * 2;}

जहां 2, एक संख्या है जिसे सार करने की आवश्यकता नहीं है। इसका उपयोग स्पष्ट है, और यह उस चीज़ का प्रतिनिधित्व नहीं करता है जिसे बाद में पुन: उपयोग किया जा सकता है।

इसके विपरीत, "500000" केवल एक संख्या नहीं है। यह एक महत्वपूर्ण मूल्य है, एक जो कार्यक्षमता में एक ब्रेकपॉइंट के विचार का प्रतिनिधित्व करता है। यह संख्या एक से अधिक स्थानों पर उपयोग की जा सकती है, लेकिन यह वह संख्या नहीं है जिसका आप उपयोग कर रहे हैं; यह सीमा / सीमा रेखा का विचार है, जिसके नीचे एक नियम लागू होता है, और ऊपर दूसरा।

एक कॉन्फ़िगरेशन फ़ाइल, या यहां तक ​​कि ए #define, constया जो कुछ भी आपकी भाषा प्रदान करता है, उसके मूल्य से भी बदतर है, इसका जिक्र कैसे किया जाता है ? यदि बाद में प्रोग्राम पर, या कुछ अन्य प्रोग्रामर को भी उस बॉर्डरलाइन की आवश्यकता होती है, ताकि सॉफ्टवेयर एक और विकल्प बनाए, तो आप खराब हो जाते हैं (क्योंकि जब यह बदलता है, तो कुछ भी आपको गारंटी नहीं देता है कि यह दोनों फाइलों में बदल जाएगा)। यह डिबगिंग के लिए स्पष्ट रूप से बदतर है।

इसके अलावा, यदि कल, सरकार "5/3/2050 से मांग करती है, तो आपको AUTHLDG-1A के बजाय AUTHLDG-122B को जोड़ने की आवश्यकता है", यह स्ट्रिंग स्थिरांक एक साधारण स्ट्रिंग स्थिरांक नहीं है। यह एक है जो एक विचार का प्रतिनिधित्व करता है; यह सिर्फ उस विचार का वर्तमान मूल्य है (जो कि "वह चीज है जिसे आप जोड़ते हैं यदि खाता 500k से ऊपर है")।

मुझे स्पष्ट करें। मैं यह नहीं कह रहा हूं कि लेख गलत है; मुझे यह बिलकुल समझ में नहीं आया; शायद यह बहुत अच्छी तरह से समझाया नहीं गया है (कम से कम मेरी सोच के लिए)।

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


21
पहेली खेलें: उन नंबरों के लिए एक अच्छा नाम क्या होगा? मुझे लगता है कि आप पाएंगे कि या तो नाम का कोई मूल्य नहीं है, या यह वह सब कुछ बताता है जो कोड पहले से वर्णन कर रहा है और अक्सर अस्पष्टता जोड़ते हुए ("लेडर्जलिमिटफॉरऑथलग 1 ए?")। मुझे लेख बिल्कुल शानदार लगा क्योंकि यह कितना प्रासंगिक है। मैंने उन प्रणालियों को बनाए रखा है जो दोनों दृष्टिकोणों का उपयोग करते हैं, और मैं आपको बता सकता हूं कि व्यावसायिक नियम कोड में हैं - इससे उन्हें ट्रैक करना, बनाए रखना और समझना बहुत आसान हो जाता है। जब आप कॉन्फ़िगरेशन का उपयोग करते हैं, तो आप इसे बेहतर बनाते हैं - यह बहुत अधिक महंगा है।
लुआं

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

उपयुक्त रूप से उन्नत भाषाओं के लिए, कॉन्फ़िगरेशन वास्तविक उप-रेखाओं का रूप लेता है, न कि तार का।
थोरबजोरन रावन एंडरसन

जवाबों:


100

लेखक समय से पहले अमूर्तता के खिलाफ चेतावनी दे रहा है।

यह रेखा if (ledgerAmt > 500000)उस तरह के व्यावसायिक नियम की तरह दिखती है, जिसकी अपेक्षा आप बड़े जटिल व्यावसायिक sytems के लिए करते हैं, जिनकी आवश्यकताएं अविश्वसनीय रूप से जटिल और सटीक और अच्छी तरह से प्रलेखित हैं।

आमतौर पर उन प्रकार की आवश्यकताओं को उपयोगी पुन: प्रयोज्य तर्क के बजाय असाधारण / धार मामले हैं। उन आवश्यकताओं को आमतौर पर इंजीनियरों द्वारा बजाय व्यापार विश्लेषकों और विषय वस्तु विशेषज्ञों द्वारा स्वामित्व और बनाए रखा जाता है

(ध्यान दें कि इन मामलों में व्यावसायिक विश्लेषकों / विशेषज्ञों द्वारा आवश्यकताओं का 'स्वामित्व' आमतौर पर होता है जहां विशेषज्ञ क्षेत्रों में काम करने वाले डेवलपर्स के पास पर्याप्त डोमेन विशेषज्ञता नहीं होती है; हालाँकि मैं अभी भी डेवलपर्स और डोमेन विशेषज्ञों के बीच पूर्ण संचार / सहयोग की अपेक्षा करूँगा ताकि वे सुरक्षा कर सकें। अस्पष्ट या खराब लिखित आवश्यकताएं।)

उन प्रणालियों को बनाए रखने के लिए जिनकी आवश्यकताओं को किनारे के मामलों और अत्यधिक जटिल तर्क से भरा हुआ है, आमतौर पर उस तर्क को उपयोगी रूप से अमूर्त करने का कोई तरीका नहीं है या इसे अधिक बनाए रखने योग्य है; अमूर्त निर्माण की कोशिशों को आसानी से उलटा पड़ सकता है - न केवल समय बर्बाद करने के कारण, बल्कि कम रख-रखाव कोड के परिणामस्वरूप भी।

यह एक कॉन्फ़िग फ़ाइल, या यहां तक ​​कि एक #define, const या जो कुछ भी आपकी भाषा प्रदान करता है, उसके मूल्य को शामिल करने से भी बदतर है? यदि बाद में प्रोग्राम पर, या कुछ अन्य प्रोग्रामर को भी उस बॉर्डरलाइन की आवश्यकता होती है, ताकि सॉफ्टवेयर एक और विकल्प बनाए, तो आप खराब हो जाते हैं (क्योंकि जब यह बदलता है, तो कुछ भी आपको गारंटी नहीं देता है कि यह दोनों फाइलों में बदल जाएगा)। यह डिबगिंग के लिए स्पष्ट रूप से बदतर है।

इस तरह के कोड को इस तथ्य से संरक्षित किया जाता है कि कोड में संभवतः आवश्यकताओं के लिए एक-से-एक मैपिंग है; जब एक डेवलपर जानता है कि 500000आंकड़ा आवश्यकताओं में दो बार प्रकट होता है, तो उस डेवलपर को भी पता है कि यह कोड में दो बार दिखाई देता है।

500000आवश्यकताओं के दस्तावेज़ में कई स्थानों पर दिखाई देने वाले अन्य (समान रूप से संभावित) परिदृश्य पर विचार करें , लेकिन विषय विशेषज्ञ विशेषज्ञ उनमें से केवल एक को बदलने का निर्णय लेते हैं; वहाँ आपको और भी बुरा जोखिम होता है कि किसी को constमूल्य बदलने का एहसास नहीं हो सकता 500000है इसका इस्तेमाल अलग-अलग चीजों के लिए किया जाता है - इसलिए डेवलपर इसे एक में बदल देता है और केवल उसे कोड में पाता है, और कुछ को तोड़ता है जो वे एहसास नहीं कि वे बदल गए थे।

यह परिदृश्य कानूनी / वित्तीय सॉफ़्टवेयर (जैसे इंश्योरेंस कोटेशन लॉजिक) के बारे में बहुत कुछ होता है - जो लोग ऐसे दस्तावेज़ लिखते हैं वे इंजीनियर नहीं होते हैं, और उन्हें कोई समस्या कॉपी नहीं होती है + कल्पना का पूरा हिस्सा चिपकाना, कुछ शब्दों / संख्याओं को संशोधित करना, लेकिन इसमें से अधिकांश वही छोड़ रहा है।

उन परिदृश्यों में, कॉपी-पेस्ट आवश्यकताओं से निपटने का सबसे अच्छा तरीका कॉपी-पेस्ट कोड लिखना है, और कोड को आवश्यकताओं के समान दिखने के लिए (सभी डेटा हार्ड-कोडिंग सहित) संभव है।

ऐसी आवश्यकताओं की वास्तविकता यह है कि वे आमतौर पर लंबे समय तक कॉपी + पेस्ट नहीं रहते हैं, और मान कभी-कभी नियमित रूप से बदलते हैं, लेकिन वे अक्सर मिलकर नहीं बदलते हैं, इसलिए उन आवश्यकताओं को तर्कसंगत बनाने या सार करने या सरल बनाने की कोशिश कर रहे हैं। उन्हें किसी भी तरह से कोड में केवल क्रिया आवश्यकताओं का अनुवाद करने की तुलना में एक रखरखाव सिरदर्द के अधिक बनाने समाप्त होता है।


28
एक डोमेन विशिष्ट भाषा (DSL) कोड को आवश्यकता दस्तावेज़ की तरह अधिक पढ़ने के लिए एक अच्छा तरीका हो सकता है।
इयान

13
डीएसएल का एक और फायदा यह है कि यह गलती से आवेदन, प्रस्तुति, या व्यावसायिक नियमों के साथ दृढ़ता के तर्क को भी कठिन बना देता है।
एरिक Eidt

16
यह सोचकर कि आपका एप्लिकेशन विशेष रूप से अपने स्वयं के DSL को वारंट करने के लिए पर्याप्त है, आमतौर पर हब्रीस है।
ब्रायन_ओ

8
Those requirements are typically owned and maintained by business analysts and subject matter experts, rather than by engineersजो हमेशा एक अच्छा विचार नहीं है। कभी-कभी उन आवश्यकताओं को कोड में बदलने का कार्य कोने के मामलों को प्रकट करेगा जहां आवश्यकताओं को या तो अच्छी तरह से परिभाषित नहीं किया जाता है या उन्हें इस तरह से परिभाषित किया जाता है कि यह व्यावसायिक हित के खिलाफ जाता है। यदि व्यापार विश्लेषकों और डेवलपर्स एक समान लक्ष्य प्राप्त करने पर सहयोग कर सकते हैं, तो बहुत सारी समस्याओं से बचा जा सकता है।
19

4
@BenCottrell मैं सॉफ्टवेयर को लिखना आसान बनाने के लिए नियमों को बदलने का सुझाव नहीं दे रहा था। लेकिन जब आपके पास नियमों में बहुत सारी शर्तें हैं तो यह पूरी तरह से संभव है कि पहली बार में नियमों को परिभाषित करते समय उन लोगों के बीच कुछ बातचीत छूट गई थी। लेकिन जैसा कि आप विनिर्देश को कोड में बदलते हैं, डेवलपर यह नोटिस करने के लिए बाध्य है कि उन स्थितियों के बीच एक संभावित बातचीत है। इस बिंदु पर यह संभव है कि डेवलपर पाता है कि विनिर्देश की एक सख्त व्याख्या एक अनजाने मूल्य की ओर ले जाती है जो ग्राहकों को सिस्टम को गेम करने की अनुमति देगा।
कास्परड

44

लेख का एक अच्छा बिंदु है। एक कॉन्‍फ़‍िगरेशन फ़ाइल में स्थिरांक निकालने के लिए यह एक बुरा अभ्यास कैसे हो सकता है? यदि यह अनावश्यक रूप से कोड को उलझाता है तो यह एक बुरा अभ्यास हो सकता है। कोड में सीधे एक मान होने से यह विन्यास फाइल से पढ़ने की तुलना में बहुत सरल है, और लिखित रूप में कोड का पालन करना आसान है।

इसके अलावा, कल, सरकार "5/3/2050 से, आपको AUTHLDG-1A के बजाय AUTHLDG-122B को जोड़ने की आवश्यकता है"।

हाँ, तो आप कोड को बदल दें। लेख का मुद्दा यह है कि कॉन्फ़िगरेशन फ़ाइल को बदलने की तुलना में कोड को बदलना अधिक जटिल नहीं है।

यदि आप अधिक जटिल तर्क प्राप्त करते हैं, तो लेख में वर्णित दृष्टिकोण स्केल नहीं करता है, लेकिन मुद्दा यह है कि आपको एक निर्णय कॉल करना होगा, और कभी-कभी सबसे सरल समाधान सबसे अच्छा होता है।

आप कैसे जानते हैं कि आपको बाद में इसकी आवश्यकता नहीं होगी? या उस मामले के लिए कोई और?

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

सॉफ्टकोडिंग वास्तव में चिंताओं के अलग होने का सवाल है । आप सॉफ्टकोड जानकारी जिसे आप जानते हैं कि कोर एप्लीकेशन लॉजिक से स्वतंत्र रूप से बदल सकते हैं । आप डेटाबेस से कनेक्शन स्ट्रिंग को कभी भी हार्डकोड नहीं करेंगे, क्योंकि आप जानते हैं कि यह एप्लिकेशन लॉजिक से स्वतंत्र रूप से बदल सकता है और आपको इसे अलग-अलग वातावरणों के लिए अलग करने की आवश्यकता होगी। एक वेब ऐप में हम HTML टेम्प्लेट और स्टाइल शीट से व्यावसायिक तर्क को अलग करना पसंद करते हैं, क्योंकि वे अलग-अलग लोगों द्वारा स्वतंत्र रूप से बदल सकते हैं और यहां तक ​​कि बदल सकते हैं।

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


4
अक्सर यह कॉन्फ़िगरेशन फ़ाइल की तुलना में कोड बदलने के लिए बहुत अधिक जटिल होता है। आपको पूर्व के लिए एक डेवलपर और एक बिल्ड सिस्टम / रिलीज़ चक्र की आवश्यकता हो सकती है, जबकि बाद वाले को केवल एक अनुकूल कॉन्फ़िगरेशन UI में एक बॉक्स में नंबर बदलने की आवश्यकता होती है।
ऑरेंजडॉग

6
@OrangeDog हाँ, यह पहली बार में कैसा दिखता है। लेकिन अगर आप इस तरह की चीजें करते हैं, तो कॉन्फ़िगर UI कुछ भी नहीं बल्कि मैत्रीपूर्ण होने वाला है, जिसमें सैकड़ों पूरी तरह से अर्थहीन टेक्स्ट-बॉक्स हैं जो आपसे पूछते हैं कि कौन क्या जानता है। और अब आपको यूआई का निर्माण करना होगा, और इसे दस्तावेज़ करना होगा। ध्यान रखें, इसका मतलब यह नहीं है कि कॉन्फ़िगरेशन कभी भी एक अच्छा तरीका नहीं है - ऐसे मामले हैं जहां यह बिल्कुल सही विकल्प है। लेकिन लेख में किसी भी उदाहरण में नहीं। और पिछली बार एक कानून में सिर्फ संख्या कब बदली गई थी? पिछली बार जब यहां वैट नियम बदले गए, तो हमें वैसे भी सभी गणनाओं को फिर से करना था।
लुआं

2
@OrangeDog: आप मान रहे हैं, कि सॉफ़्टवेयर का कॉन्फ़िगरेशन आपको उस चेक के लिए आवश्यक हुक प्रदान करता है, जिसे आपको बनाने की आवश्यकता है। ध्यान दें कि ओपी में हर ifएक अलग चर पर आधारित है! यदि आपके लिए आवश्यक चर कॉन्फ़िगरेशन से सुलभ नहीं है, तो आपको सॉफ़्टवेयर को किसी भी तरह संशोधित करना होगा।
Matthieu M.

2
@OrangeDog तो आप यह सुझाव दे रहे हैं कि एक देव / क्ष / विमोचन चक्र और उपयुक्त परीक्षण के बिना, एक सॉफ्टवेयर अनुप्रयोग के तर्क में महत्वपूर्ण परिवर्तन होना चाहिए ?
एनपीएसएफ ३०००

3
@OrangeDog: ठीक है आप उदाहरण में तर्क को कॉन्फ़िगर करने के लिए YAML का उपयोग करते हैं। चूँकि तर्क में सशर्त नियम शामिल हैं, इसलिए आप YAML में इन शर्तों का प्रतिनिधित्व करने का एक तरीका ढूंढते हैं। बधाई हो, आपने पायथन को फिर से स्थापित किया है। पाइथन में पूरा ऐप क्यों नहीं लिखा?
जैक्सबी

26

इस लेख में 'एंटरप्राइज रूल इंजन' के बारे में बात की गई है, जो संभवतः इस बात का एक बेहतर उदाहरण है कि वह किसके खिलाफ बहस कर रहा है।

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

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

<statecode id="AZ">
    <document id="SR008-04X"/>
    <document id="SR008-04XI"/>
</statecode>

शायद आप भी बही की राशि में डाल देंगे?

<statecode id="ALL">
    <document id="AUTHLDG-1A" rule="ledgerAmt >= 50000"/>
</statecode>

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

यह ध्यान दिया जाना चाहिए कि यह लेख 2007 से है जब इस तरह की चीज एक सामान्य दृष्टिकोण थी।

आजकल हम शायद निर्भरता इंजेक्शन (DI) के साथ समस्या को हल करेंगे । यानी, आपके पास एक 'हार्ड कोडेड' होगा

InvoiceRules_America2007 : InvoiceRules

जिसे आप एक हार्ड कोडित या अधिक विन्यास के साथ बदलेंगे

InvoiceRules_America2008 : InvoiceRules

जब कानून या व्यावसायिक आवश्यकताएं बदल गईं।


4
शायद आपको "DI" को परिभाषित करना चाहिए। और शायद थोड़ा और समझाएं।
तुलसी Bourque

9
वह फ़ाइल स्रोत नियंत्रण प्रणाली में क्यों नहीं होगी?
20:30 पर JDługosz

2
यदि यह क्लाइंट विशिष्ट है, तो क्या कोडित संस्करण में ifप्रत्येक क्लाइंट के लिए अलग-अलग मान देने के लिए कथनों की एक बड़ी गड़बड़ी है ? ऐसा लगता है कि कुछ ऐसा होना चाहिए जो कि एक कॉन्फिगर फाइल में होना चाहिए। एक तरह की फ़ाइल या किसी अन्य में होने के नाते, बाकी सभी समान होना, फ़ाइल को नियंत्रित / ट्रैक / बैकअप नहीं करने का एक कारण नहीं है। @ewan कह रहा है कि किसी कारण से प्रोजेक्ट के हिस्से के रूप में एक DSL फाइल को बचाया नहीं जा सकता है, जब इमेज और साउंड फाइल और डॉक्यूमेंट जैसी गैर-कोड संपत्तियां भी निश्चित रूप से है
जडलुगोज़

2
आपको वास्तव में अपने XML से "50000" मूल्य को वापस लेना चाहिए और इसे एक अलग कॉन्फ़िगरेशन फ़ाइल में डालना चाहिए, क्या आपको नहीं लगता है? ... और यह 500000 माना जाता है, वैसे
वाइल्डकार्ड

1
@ Jdlugosz एक ERE की अवधारणा है कि आप सिस्टम खरीदते हैं और फिर इसे अपनी आवश्यकताओं के लिए कॉन्फ़िगर करते हैं। शायद इसलिए कि आंतरिक देव इन 'लचीली' प्रणालियों के साथ प्रतिस्पर्धा में थे, वे उनका अनुकरण करने की कोशिश करेंगे। विन्यास का परिवर्तन नियंत्रण, यहां तक ​​कि आईबीएम जैसी बड़ी कंपनियों के सिस्टम में भी अक्सर होता था। विक्रय बिंदु त्वरित परिवर्तन था
इवान

17

इसके विपरीत, "500000" केवल एक संख्या नहीं है। यह एक महत्वपूर्ण मूल्य है, एक जो कार्यक्षमता में एक ब्रेकपॉइंट के विचार का प्रतिनिधित्व करता है। इस नंबर को एक से अधिक स्थानों पर उपयोग किया जा सकता है, लेकिन यह वह संख्या नहीं है जिसका आप उपयोग कर रहे हैं, यह सीमा / सीमा रेखा का विचार है, जिसके नीचे एक नियम लागू होता है, और जिसके ऊपर एक और।

और यह होने के द्वारा व्यक्त किया जाता है (और मैं यह तर्क दे सकता हूं कि टिप्पणी भी बेमानी है):

 if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

यह सिर्फ वही दोहरा रहा है जो कोड कर रहा है:

LEDGER_AMOUNT_REQUIRING_AUTHLDG1A=500000
if (ledgerAmnt >= LEDGER_AMOUNT_REQUIRING_AUTHLDG1A) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
}

ध्यान दें कि लेखक मानता है कि 500000 का अर्थ इस नियम से बंधा है; यह ऐसा मूल्य नहीं है जो अन्यत्र पुन: उपयोग किया जा सकता है या होने की संभावना है:

एक और केवल व्यावसायिक नियम बदलते हैं कि यह पूर्ववर्ती शीतल कोडिंग कभी भी खाता हो सकता है जो कि खाता राशि में एक परिवर्तन है जिसके लिए एक फॉर्म AUTHLDG-1A की आवश्यकता होती है। किसी अन्य व्यवसाय नियम परिवर्तन के लिए और भी अधिक काम की आवश्यकता होगी - कॉन्फ़िगरेशन, प्रलेखन, कोड, आदि

मेरे विचार में, लेख का मुख्य बिंदु यह है कि कभी-कभी एक संख्या सिर्फ एक संख्या होती है: इसका कोई अतिरिक्त अर्थ नहीं है कि कोड में क्या बताया गया है और इसका कहीं और इस्तेमाल होने की संभावना नहीं है। इसलिए, अजीब तरह से संक्षेप में कि कोड क्या कर रहा है (अब) एक चर नाम में केवल हार्ड-कोडित मूल्यों से बचने के लिए अनावश्यक पुनरावृत्ति है।


2
यदि आपने निरंतरता का परिचय दिया है LEDGER_AMOUNT_REQUIRING_AUTHLDG1A, तो आप टिप्पणी को कोड में नहीं लिखेंगे। प्रोग्रामर द्वारा टिप्पणियां अच्छी तरह से बनाए नहीं रखी जाती हैं। यदि राशि कभी बदल गई, तो ifस्थिति और टिप्पणी सिंक से बाहर हो जाएगी। इसके विपरीत, स्थिरांक LEDGER_AMOUNT_REQUIRING_AUTHLDG1Aकभी भी अपने आप से सिंक से बाहर नहीं निकलता है और यह अनावश्यक उद्देश्य के बिना अपने उद्देश्य की व्याख्या करता है।
ज़ीरोएन

2
@ZeroOne: सिवाय इसके कि यदि व्यावसायिक नियम "500K के लेजर या उससे अधिक के AUTHLDG-1A और AUTHLDG-2B" की आवश्यकता होती है, तो यह बहुत संभावना है कि जो व्यक्ति attachDocument("AUTHLDG-2B");लाइन जोड़ता है वह उसी समय निरंतर नाम को अपडेट करने में विफल हो जाएगा। इस मामले में, मुझे लगता है कि कोड न तो एक टिप्पणी और ही एक व्याख्यात्मक चर के साथ काफी स्पष्ट है । (हालांकि यह कोड टिप्पणियों के माध्यम से व्यावसायिक आवश्यकताओं के दस्तावेज़ के उपयुक्त अनुभाग को इंगित करने का एक सम्मेलन हो सकता है। इस तरह के एक सम्मेलन के तहत, एक कोड टिप्पणी जो कि यहां उपयुक्त होगी।)
बर्बाद

@ruakh, ठीक है, तो मैं निरंतर बुलाया जा सकता LEDGER_AMOUNT_REQUIRING_ADDITIONAL_DOCUMENTSहूँ (जो मैं शायद पहली जगह में किया जाना चाहिए)। मैं व्यावसायिक आवश्यकता आईडी को जीआईटी प्रतिबद्ध संदेशों में डालने की आदत में हूं, स्रोत कोड में नहीं।
ज़ीरोएन

1
@ZeroOne: लेकिन AUTHLDG-3C के लिए लेज़र राशि वास्तव में एक अधिकतम है । और AUTHLDG-4D के लिए उपयुक्त खाता बही राशि राज्य पर निर्भर करती है। (क्या आपको अभी तक इस बिंदु पर जाना है? इस प्रकार के कोड के लिए, आप चाहते हैं कि आपका कोड व्यावसायिक नियमों को प्रतिबिंबित करे, न कि कुछ व्यावसायिक नियमों का पालन करने का प्रयास करें, क्योंकि व्यावसायिक नियमों के विकास की अपेक्षा करने का कोई कारण नहीं है। आपके द्वारा अपनाया गया सार।)
बर्बाद करें

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

8

अन्य उत्तर सही हैं, और विचारशील हैं। लेकिन यहाँ मेरा छोटा और मीठा जवाब है।

  Rule/value          |      At Runtime, rule/value…
  appears in code:    |   …Is fixed          …Changes
----------------------|------------------------------------
                      |                 |
  Once                |   Hard-code     |   Externalize
                      |                 |   (soft-code)
                      |                 |
                      |------------------------------------
                      |                 |
  More than once      |   Soft-code     |   Externalize
                      |   (internal)    |   (soft-code)
                      |                 |
                      |------------------------------------

यदि नियम और विशेष मान कोड में एक स्थान पर दिखाई देते हैं, और रनटाइम के दौरान नहीं बदलते हैं, तो हार्ड-कोड जैसा कि प्रश्न में दिखाया गया है।

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

यदि रनटाइम के दौरान नियम या विशेष मान बदल सकते हैं, तो आपको उन्हें बाहरी करना होगा। यह आमतौर पर एक डेटाबेस में मूल्यों को अद्यतन करने के द्वारा किया जाता है। या डेटा दर्ज करने वाले उपयोगकर्ता द्वारा मैन्युअल रूप से मेमोरी में मान अपडेट करें। यह एक पाठ फ़ाइल (XML, JSON, सादा पाठ, जो भी हो) में मूल्यों को संग्रहीत करके भी किया जाता है जो फ़ाइल संशोधन तिथि-समय परिवर्तन के लिए बार-बार स्कैन किया जाता है।


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

इस उत्तर और कार्यान्वयन के बारे में टिप्पणी से सहमत हैं। स्टफ I पर काम कई संगठनों द्वारा कार्यान्वित किया जाता है, और उनमें से कई के पास आवश्यक रूप से भिन्न मूल्य हैं। हम इन 'सेटिंग्स' को कॉन्फिगर फाइल के बजाय एक डेटाबेस में स्टोर करते हैं, लेकिन सिद्धांत यह है कि हम अपने सॉफ़्टवेयर के विभिन्न बिल्ड प्रत्येक कंपनी के लिए नहीं बनाना चाहते हैं जो इसे लागू करता है (फिर हर बार अपग्रेड होने पर उन विभिन्न बिल्ड को दोहराता है) ।
रोज़ी

7

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

दिए गए उदाहरण में, यह अंतर का एक सफेद नहीं करता है कि क्या दिए गए मान इनलाइन मानों के रूप में हार्डकोड किए गए हैं, या उन्हें const के रूप में परिभाषित किया गया है।

यह आस-पास का कोड है जो उदाहरण को एक रखरखाव और कोडिंग हॉरर बना देगा। अगर वहाँ है कोई आसपास के कोड, तो टुकड़ा ठीक, कम से कम लगातार पुनर्रचना के माहौल में है। ऐसे वातावरण में जहां रिफ्लेक्टिंग नहीं होता है, उस कोड के रखवाले पहले से ही मर चुके हैं, ऐसे कारणों से जो जल्द ही स्पष्ट हो जाएंगे।

देखें, यदि इसके आसपास कोड है, तो खराब चीजें स्पष्ट रूप से होती हैं।

पहली बुरी बात यह है कि 50000 के मूल्य का उपयोग कहीं और मूल्य के लिए किया जाता है, कहते हैं, उस बही की राशि जिस पर कुछ राज्यों में कर की दर बदल जाती है ... फिर जब परिवर्तन होता है, तो अनुचर के पास कोई रास्ता नहीं होता है, जब वह पाता है कोड में 50000 के दो उदाहरण, चाहे उनका मतलब समान 50k हो, या पूरी तरह से असंबंधित 50ks। और क्या आपको 49999 और 50001 के लिए भी खोज करनी चाहिए, यदि किसी ने उन्हें स्थिरांक के रूप में इस्तेमाल किया है, तो भी? यह एक अलग सेवा की एक कॉन्फ़िगर फ़ाइल में उन चर को प्लैंक करने के लिए कॉल नहीं है: लेकिन इनलाइन को हार्डकोड करना भी स्पष्ट रूप से गलत है। इसके बजाय, उन्हें निरंतर या परिभाषित और वर्ग या फ़ाइल के भीतर होना चाहिए जिसमें उनका उपयोग किया जाता है। यदि 50k के दो उदाहरण एक ही निरंतर का उपयोग करते हैं, तो वे संभवतः एक ही विधायी प्रतिबंध का प्रतिनिधित्व करते हैं; यदि नहीं, तो वे शायद नहीं करते; और किसी भी तरह से, उनके पास एक नाम होगा,

फ़ाइलनामों को एक फ़ंक्शन - अनुलग्नकडोमेनमेंट () में पारित किया जा रहा है - जो पथ या विस्तार के बिना आधार फ़ाइलनाम को स्ट्रिंग के रूप में स्वीकार करता है। फ़ाइलनाम अनिवार्य रूप से, कुछ फाइल सिस्टम, या डेटाबेस के लिए विदेशी कुंजियाँ हैं, या जहाँ भी संलग्नक () फ़ाइलें प्राप्त होती हैं। लेकिन तार आपको इस बारे में कुछ नहीं बताते हैं - कितनी फाइलें हैं? वे किस प्रकार की फ़ाइल हैं? आपको कैसे पता चलेगा, एक नए बाजार में खुलने पर, क्या आपको इस फ़ंक्शन को अपडेट करने की आवश्यकता है? उन्हें किस प्रकार की चीज से जोड़ा जा सकता है? अनुरक्षक पूरी तरह से अंधेरे में छोड़ दिया जाता है, और उसके पास सब कुछ एक स्ट्रिंग है, जो कोड में कई बार दिखाई दे सकता है और हर बार प्रकट होने पर अलग-अलग चीजों का मतलब हो सकता है। एक जगह पर, "SR008-04X" एक धोखा कोड है। दूसरे में, यह चार SR008 बूस्टर रॉकेट ऑर्डर करने के लिए एक कमांड है। यहाँ है' सा फिल्नाम? क्या ये संबंधित हैं? किसी ने सिर्फ एक फ़ाइल "CLIENT" का उल्लेख करने के लिए उस फ़ंक्शन को बदल दिया। तब आपको, गरीब अनुचर को बताया गया है कि "ग्राहक" फ़ाइल का नाम बदलकर "ग्राहक" होना चाहिए। लेकिन स्ट्रिंग "CLIENT" कोड में 937 बार दिखाई देता है ... आप भी कहाँ देखना शुरू करते हैं?

खिलौना समस्या है कि मूल्यों सब असामान्य हैं और यथोचित कोड में अद्वितीय होने की गारंटी दी जा सकती है। "1" या "10" नहीं बल्कि "50,000"। "क्लाइंट" या "रिपोर्ट" नहीं बल्कि "SR008-04X"।

Strawman कि गहनता से अपारदर्शी स्थिरांक की समस्या का समाधान करने का एकमात्र अन्य तरीका उन्हें कुछ असंबंधित सेवा के कॉन्फ़िग फ़ाइल में को अलग करने है।

साथ में, आप किसी भी तर्क को सही साबित करने के लिए इन दो नतीजों का उपयोग कर सकते हैं।


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

4
उदाहरण टूट नहीं जाता क्योंकि यह एक खिलौना समस्या है। आसपास का कोड हमेशा भयानक होगा क्योंकि सॉफ्टवेयर द्वारा निष्पादित किए जाने वाले व्यवसाय के नियम डरावने हैं । नियमों के इंजन और डीएसएल और व्हाट्सएप के साथ इस मूलभूत चुनौती को साइड-स्टेप करने का प्रयास अक्सर प्रोग्रामर शिथिलता है , क्योंकि सीएस की समस्याओं को हल करना कर रूपों की पेचीदगियों को सुलझाने की तुलना में अधिक सुखद है। 'लालित्य' को प्राप्त करने के प्रयास अक्सर मूर्खों के काम आते हैं क्योंकि सॉफ्टवेयर का अंतिम कार्य एक जटिल आपदा को मॉडल बनाना है।
whatsisname

व्यवसाय के नियम डरावने हो सकते हैं, लेकिन यह अपने आप में इस तरह के औसत दर्जे का प्रक्रियात्मक कोड लिखने का बहाना नहीं है। (मैं पापाडिमौलिस से सहमत हूं कि यह विन्यास की तुलना में कोड में नियमों को बनाए रखना और बनाए रखना आसान है, मुझे लगता है कि यह बेहतर कोड होना चाहिए।) मुझे लगता है कि समस्या जादू संख्या नहीं है, यह दोहराया है if (...) { attachDocument(...); }
डेविड मोल्स

2

इसमें कई मुद्दे हैं।

एक समस्या यह है कि सभी नियमों को कार्यक्रम के बाहर आसानी से कॉन्फ़िगर करने योग्य बनाने के लिए एक नियम इंजन बनाया जाना चाहिए। इस तरह के मामलों में जवाब सबसे अधिक बार नहीं है। नियम अजीब तरीके से बदल रहे होंगे जो भविष्यवाणी करना कठिन है जिसका मतलब है कि जब भी कोई बदलाव होता है तो नियम इंजन को बढ़ाया जाना चाहिए।

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

यह अनुमति देता है कि प्रत्येक नियम की अपनी वैधता है, प्रत्येक वर्ष कुछ नियम बदलते हैं, जब परमिट दिया जाता है या चालान जारी किया जाता है, तो कुछ परिवर्तन पर रोक लगाई जाती है। यह नियम स्वयं जांच के लिए है कि इसे किस संस्करण में लागू करना है।

साथ ही यह स्थिर है कि कोड में कहीं और इसका दुरुपयोग नहीं किया जा सकता है।

फिर सभी नियमों की एक सूची है और सूची को लागू करें।

एक और मुद्दा यह है कि स्थिरांक को कैसे संभालना है। 500000 असंगत लग सकते हैं, लेकिन यह सुनिश्चित करने के लिए बहुत सावधानी बरती जानी चाहिए कि यह सही ढंग से परिवर्तित हो जाए। यदि कोई फ्लोटिंग पॉइंट अंकगणित लागू किया जाता है तो इसे 500,000.00001 में परिवर्तित किया जा सकता है, इसलिए 500,000.00000 के साथ तुलना विफल हो सकती है। या इससे भी बदतर 500000 हमेशा की तरह काम करता है, लेकिन परिवर्तित होने पर किसी तरह 565000 विफल हो जाते हैं। सुनिश्चित करें कि रूपांतरण स्पष्ट है और आपके द्वारा संकलक द्वारा अनुमान लगाया गया है। अक्सर इसका उपयोग करने से पहले इसे कुछ BigInteger या BigDecimal में परिवर्तित करके किया जाता है।


2

हालांकि यह सीधे प्रश्न में उल्लिखित नहीं है, मैं यह नोट करना चाहूंगा कि कोड में व्यावसायिक तर्क को दफनाना महत्वपूर्ण नहीं है ।

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

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

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

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


बिलकुल यही बात है जो मैं सोच रहा था!!! जब तर्क को कोड में गहराई से दफन किया जाता है, तो एक डोमेन / विषय वस्तु विशेषज्ञ या व्यावसायिक उपयोगकर्ता उन मूल्यों और तर्क को कैसे देख सकता है जो सही होने के लिए उपयोग में हैं और सिस्टम के व्यवहार का निदान करते हैं? एक विन्यास फाइल जो करती है वह सेटिंग्स को दृश्यमान बनाती है । व्यावसायिक नियमों की दृश्यता को बढ़ावा देने के लिए कुछ साधन होने चाहिए - भले ही वह कोडिंग "कठिन" हो। मैं एक पतली कक्षा या उन वर्गों के समूह को स्वीकार कर सकता हूं जो नौकरी करते हैं, अन्य चिंताओं में मिश्रण किए बिना - जब तक कि व्यापार उपयोगकर्ता के पास उन्हें एक्सेस करने और समझने का साधन है।
एरिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.