मजबूत कोड क्या परिभाषित करता है?


42

मेरे प्रोफेसर इस जावा उदाहरण का जिक्र करते रहते हैं जब वे "मजबूत" कोड की बात करते हैं:

if (var == true) {
    ...
} else if (var == false) {
    ...
} else {
    ...
}

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

मैं संदिग्ध हूं, हालांकि। यदि चर एक बूलियन है, तो तीसरा राज्य तार्किक रूप से असंभव होने पर तीसरे राज्य की जांच करने का क्या मतलब है?

"त्रुटि के रूप में ऐसी कोई बात नहीं है" के रूप में अच्छी तरह से हास्यास्पद लगता है; यहां तक ​​कि Google एप्लिकेशन उपयोगकर्ता को चुपचाप निगलने के बजाय सीधे त्रुटियों को दिखाते हैं या किसी तरह उन्हें वैध स्थिति मानते हैं। और यह अच्छा है - मुझे यह जानना पसंद है कि जब कुछ गलत होता है। और ऐसा लगता है कि यह कहने का दावा है कि किसी आवेदन में कभी कोई त्रुटि नहीं होगी।

तो "मजबूत कोड" की वास्तविक परिभाषा क्या है ?



4
यह केवल एक जोरदार-टाइप की हुई भाषा में होगा। जोरदार टाइप की गई भाषा में टाइप बूलियन का एक वेरिएबल (कुछ पूर्णांक बूलियन के रूप में प्रस्तुत नहीं होता है), केवल सही या गलत हो सकता है, कोई तीसरा विकल्प नहीं है ...
मार्जन वेनेमा

23
उससे पूछें कि आप तीसरे मामले पर कवरेज का परीक्षण कैसे करेंगे, क्योंकि मजबूत कोड को निश्चित रूप से परीक्षण की आवश्यकता होनी चाहिए, और यदि आप तीसरे मामले का परीक्षण करने का प्रबंधन नहीं करते हैं, तो आप किसी भी कीड़े को खोजने में सक्षम नहीं होंगे जो वहां दुबक सकते हैं।
gbjbaanb 13

2
@ मार्जन - एक जोरदार टाइप की भाषा में नहीं, जो सबसे अधिक संभवत: सिर्फ इसलिए लिखेगा: अगर (var) {} और {}
kevin cline

2
मुझे ऐसी किसी भी भाषा की जानकारी नहीं है, जहाँ x और x दोनों सही हों। ध्यान दें कि मैंने "if (x == true) ..." का सुझाव नहीं दिया था; मैं ऐसी तुलनाओं से घृणा करता हूं।
केविन क्लाइन

जवाबों:


33

जब तीसरा राज्य तार्किक रूप से असंभव हो तो तीसरे राज्य की जाँच करने का क्या मतलब है?

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

यहां कुछ लिंक दिए गए हैं जो चर्चा करते हैं कि सॉफ्टवेयर के संदर्भ में मजबूत होने का क्या मतलब है:

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


13
यदि यह जावा और ग # दोनों को एक अशक्त बूलियन था, तो नल को पहले चेक किया जाना चाहिए।
एसेन स्कोव पेडरसन

लगता है कि कोई बिल्ली या कुत्ता क्या है, इसकी परिभाषा पर कोई सार्वभौमिक सहमति नहीं है।
ट्यूलेंस कोर्डोवा

11

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

विकल्प ए।

if (var == true) {
    ...
} else if (var == false) {
    ...
} else {
    ...
}

विकल्प बी

if (var == true) {
    ...
} else {
    ...
}

मैं जोर देता हूं विकल्प B अधिक मजबूत है .....

कोई भी ट्विट आपको अनपेक्षित त्रुटियों को संभालने के लिए कह सकता है। जब आप उनके बारे में सोचते हैं तो वे आमतौर पर पता लगाने में आसान होते हैं। आपके प्रोफेसर ने जो उदाहरण दिया है, वह कुछ ऐसा नहीं है जो हो सकता है, इसलिए यह बहुत खराब उदाहरण है।

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

विकल्प बी परीक्षण के लिए तुच्छ है।

अगली समस्या, आप प्रोफेसर से यह प्रश्न पूछें "क्या आप चाहते हैं कि मैं इसके बारे में ऐसा करूं यदि एक बूलियन न तो सच्चा है और न ही गलत है?" यह एक बहुत ही दिलचस्प चर्चा में नेतृत्व करना चाहिए .....

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

विकल्प ए मुझे मारता है विकल्प बी मुझे जीवित रहने का एक भी मौका देता है।

लेकिन रुको - यह स्पेस शटल रीवेंट्री का एक सिमुलेशन है - फिर क्या? गर्भपात तो आप इसके बारे में जानते हैं। एक अच्छे विचार की तरह लग रहा है? - नहीं - क्योंकि आपको उस कोड के साथ परीक्षण करने की आवश्यकता है जिसे आप जहाज करने की योजना बनाते हैं।

विकल्प ए अनुकरण के लिए बेहतर है, लेकिन इसे तैनात नहीं किया जा सकता है। यह बेकार है ऑप्शन बी परिनियोजित कोड है इसलिए सिमुलेशन लाइव सिस्टम के समान कार्य करता है।

मान लीजिए कि यह एक वैध चिंता थी। बेहतर तरीका यह होगा कि एप्लिकेशन लॉजिक से निपटने में त्रुटि को अलग किया जाए।

if (var != true || var != false) {
    errorReport("Hell just froze over, var must be true or false")
}
......
if (var == true){
 .... 
} else {
 .... 
}

फ्यूचर पढ़ना - थेरैक -25 एक्सरे मशीन, एरियन 5 रॉकेट विफलता और अन्य (लिंक में कई टूटे हुए लिंक हैं लेकिन पर्याप्त जानकारी है कि Google मदद करेगा)


1
".. अप्रमाणित त्रुटियां। वे आमतौर पर एक बार पता लगाने में आसान होते हैं, जब आप उनके बारे में सोचते हैं" - लेकिन जब आप उनके बारे में सोचते हैं, तो वे अब अप्रत्याशित नहीं हैं।
gbjbaanb 13

7
नहीं है कुछ सवाल अगर आपके कोड के रूप में if (var != true || var != false) {एक होना चाहिए &&बजाय।

1
मैं आसानी से एक ऐसे बूल के बारे में सोच सकता हूं जो न तो सच है और न ही झूठ है, लेकिन यह अभी भी अप्रत्याशित है। यदि आप कहते हैं कि एक बूल कुछ और नहीं हो सकता है, अगर मैं जांचता हूं कि क्या कोई अक्षर एक वर्ण वर्ण है और फिर इसे अपने पूर्णांक मान में परिवर्तित करें, मैं आसानी से उस पूर्णांक मान को 0 से कम या 9 से अधिक होने के बारे में सोच सकता हूं, लेकिन यह अभी भी है अप्रत्याशित।
gnasher729

1
नल बूलियन जावा और सी # में समर्थित हैं, और एक वास्तविक दुनिया अनुप्रयोग है। एक डेटाबेस पर विचार करें जिसमें लोगों की सूची हो। थोड़ी देर बाद आप तय करते हैं कि आपको एक लिंग (isMale) फ़ील्ड की आवश्यकता है। अशक्त का अर्थ है "कभी नहीं पूछा तो पता नहीं"; सच्चा मतलब पुरुष और झूठा मतलब महिला। (ठीक है, ट्रांस-लिंग सादगी के लिए छोड़ा गया ...)।
कीवरोन

@kiwiron: एक बेहतर समाधान एक संलयन प्रकार, "पुरुष", "महिला", "डिड नॉट आस्क" का उपयोग करने के लिए नहीं होगा। Enumerations बेहतर हैं - जब जरूरत पड़ती है तब बढ़ाया जा सकता है (आपके उदाहरण में Asexual, Hermaphrodite, "Refused to Answer" दिमाग में आते हैं)।
मटनज़

9

वास्तव में आपका कोड अधिक मजबूत नहीं है लेकिन LESS मजबूत है। अंतिम elseबस मृत कोड है जिसे आप परीक्षण नहीं कर सकते हैं।

स्पेसक्राफ्ट जैसे महत्वपूर्ण सॉफ़्टवेयर में, मृत कोड और अधिक सामान्यतः बिना कोड वाला कोड निषिद्ध है: यदि एक कॉस्मिक किरण एक एकल घटना पैदा करती है जो बदले में आपके मृत कोड को सक्रिय बनाती है, तो कुछ भी संभव है। यदि SEU मजबूत कोड के एक हिस्से को सक्रिय करता है, तो (अप्रत्याशित) व्यवहार नियंत्रण में रहता है।


मुझे नहीं लगता कि यह अंतरिक्ष में मृत कोड निषिद्ध है? यानी आप आखिरी नहीं लिख सकते? जब से तुम यह नहीं कर सकते तुम इसे नहीं डाल सकते हो? लेकिन तब इसका क्या मतलब है "यदि SEU मजबूत कोड के एक हिस्से को सक्रिय करता है, (अप्रत्याशित) व्यवहार नियंत्रण में रहता है।"
जर्जर

5
हां, अंतरिक्ष में महत्वपूर्ण सॉफ़्टवेयर परीक्षण कवरेज 100% होना चाहिए और परिणामस्वरूप अनुपलब्ध कोड (उर्फ डेड कोड) निषिद्ध है।
मौविइल

7

मुझे लगता है कि प्रोफेसर "त्रुटि" और "बग" को भ्रमित कर सकते हैं। मजबूत कोड में निश्चित रूप से कुछ / कोई बग नहीं होना चाहिए। मजबूत कोड हो सकता है, और एक शत्रुतापूर्ण वातावरण में, अच्छा त्रुटि प्रबंधन होना चाहिए (यह अपवाद से निपटने या कठोर वापसी स्थिति परीक्षण)।

मैं सहमत हूं कि प्रोफेसर का कोड उदाहरण मूर्खतापूर्ण है, लेकिन मेरा जितना मूर्खतापूर्ण नहीं है।

// Assign 3 to x
var x = 3;
x = 3;   // again, just for sure
while (x < 3 or x > 3) { x = 3; }  // being robust
if (x != 3) { ... }  // this got to be an error!

1
आखिरी अगर निश्चित रूप से ट्रिगर किया जाए, तो वास्तव में इतना प्रयास करने की आवश्यकता नहीं होगी। किसी भी अनुभवी सी प्रोग्रामर ने मूल्यों में अचानक बदलाव देखा है। बेशक तार्किक रूप से, नियंत्रित एकल-थ्रेडेड वातावरण में, ऐसा कभी नहीं होना चाहिए। वास्तविक जीवन में, अंत में यदि कोड होगा। अगर वहाँ कुछ भी उपयोगी नहीं है कि आप अंदर कर सकते हैं यदि, तो इसे कोड न करें! (मुझे एक विशेष सॉफ़्टवेयर डेवलपमेंट के दौरान एक मज़ेदार अनुभव हुआ था जहाँ मैंने कुछ असंभव होने पर शाप शब्दों के साथ एक अपवाद उठाया था ... अनुमान करें कि क्या हुआ?)।
एलेक्स

2
सच्ची कहानी:boolean x = something(); if (x) { x = True // make sure it's really true, ... }
एंड्रेस एफ।

6

रोबस्ट कोड की परिभाषा पर कोई सहमति नहीं है , क्योंकि प्रोग्रामिंग में कई चीजों के लिए यह कम या ज्यादा व्यक्तिपरक है ...

आपके प्रोफेसर द्वारा दिया गया उदाहरण भाषा पर निर्भर करता है:

  • हास्केल में, कोई Booleanभी हो सकता है Trueया False, कोई तीसरा विकल्प नहीं है
  • C ++ में, एक boolहो सकता है true, falseया (दुर्भाग्य से) कुछ संदिग्ध डाली है कि यह एक अज्ञात मामले में डाल से आते हैं ... यह चाहिए हो, लेकिन नहीं पिछले एक त्रुटि की वजह से हो सकता है,।

हालाँकि, जो आपका प्रोफेसर सलाह दे रहा है कि कोर प्रोग्राम के मध्य में होने वाली घटनाओं के लिए विलम्बित तर्क को प्रस्तुत करके कोड को अस्पष्ट किया जाए, इसलिए मैं आपको इसके बजाय, डिफेंसिव प्रोग्रामिंग की ओर इंगित करूँगा ।

विश्वविद्यालय के मामले में, आप अनुबंध की रणनीति के अनुसार डिज़ाइन को अपनाकर इसे बढ़ा सकते हैं:

  • कक्षाओं के लिए इन्वर्टर स्थापित करें (उदाहरण के लिए, सूची sizeमें आइटमों की संख्या data)
  • प्रत्येक फ़ंक्शन के लिए पूर्व-शर्तें और पोस्ट-स्थितियां स्थापित करें (उदाहरण के लिए, यह फ़ंक्शन केवल aसे कम होने के साथ लागू किया जा सकता है 10)
  • अपने प्रत्येक फ़ंक्शन के प्रवेश और निकास बिंदु पर प्रत्येक का परीक्षण करें

उदाहरण:

class List:
  def __init__(self, items):
    self.__size = len(items)
    self.__data = items

  def __invariant(self):
    assert self.__size == len(self.__data)

  def size(self):
    self.__invariant()

    return self.__size

  def at(self, index):
    """index should be in [0,size)"""
    self.__invariant()
    assert index >= 0 and index < self.__size

    return self.__data[index]

  def pushback(self, item):
    """the subsequent list is one item longer
       the item can be retrieved by self.at(self.size()-1)"""
    self.__invariant()

    self.__data.append(item)
    self.__size += 1

    self.__invariant()
    assert self.at(self.size()-1) == item

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

2
C, C ++ और Objective-C में, एक बूल का एक अनिश्चित मान हो सकता है, किसी अन्य प्रकार की तरह, लेकिन कोई भी असाइनमेंट इसे सही या गलत पर सेट करेगा और कुछ नहीं। उदाहरण के लिए: बूल बी = 0; ख ++; ख ++; ख को सच कर देगा।
gnasher729

2

आपके प्रोफेसर का दृष्टिकोण पूरी तरह से गुमराह करने वाला है।

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

Spec: If var is false then the function does "this", otherwise it does "that". 

फिर आप फ़ंक्शन लिखते हैं:

if (var == false) dothis; else dothat; 

और कोड कल्पना से मिलता है। तो आपका प्रोफेसर कहता है: क्या होगा अगर var == 42? युक्ति को देखें: यह कहता है कि फ़ंक्शन को "वह" करना चाहिए। कोड को देखें: फ़ंक्शन "वह" करता है। समारोह कल्पना से मिलता है।

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


1

मैं @ gnasher729 के कथन से सहमत हूं: आपके प्रोफेसर का दृष्टिकोण पूरी तरह से गलत है।

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

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


0

मजबूत कोड बस कोड है जो विफलताओं को अच्छी तरह से संभालता है। ना ज्य़ादा ना कम।

विफलताओं में, कई प्रकार हैं: गलत कोड, अधूरा कोड, अनपेक्षित मान, अनपेक्षित अवस्थाएँ, अपवाद, संसाधन थकावट, .... Robust code ये अच्छी तरह से संभालता है।


0

मैं उस कोड पर विचार करूंगा जिसे आपने रक्षात्मक प्रोग्रामिंग का उदाहरण दिया है (कम से कम जैसा कि मैं शब्द का उपयोग करता हूं)। रक्षात्मक प्रोग्रामिंग का हिस्सा उन विकल्पों को बनाना है जो सिस्टम के बाकी हिस्सों के व्यवहार के बारे में बनी धारणाओं को कम करते हैं। उदाहरण के लिए, इनमें से कौन बेहतर है:

for (int i = 0; i != sequence.length(); ++i) {
    // do something with sequence[i]
}

या:

for (int i = 0; i < sequence.length(); ++i) {
    // do something with sequence[i]
}

(यदि आपको अंतर देखने में परेशानी हो रही है, तो लूप टेस्ट की जांच करें: पहला उपयोग !=, दूसरा उपयोग <)।

अब, अधिकांश परिस्थितियों में, दो छोरों का एक ही तरह से व्यवहार होगा। हालांकि, पहले (साथ तुलना !=) एक धारणा बनाता है जिसे iपुनरावृत्ति के बाद केवल एक बार बढ़ाया जाएगा। यदि यह मान को छोड़ देता है, sequence.length()तो लूप अनुक्रम की सीमा से आगे जारी रह सकता है और त्रुटि का कारण बन सकता है।

आप इसलिए यह तर्क दे सकते हैं कि दूसरा कार्यान्वयन अधिक मजबूत है: यह इस बारे में मान्यताओं पर निर्भर नहीं करता है कि क्या लूप बॉडी में परिवर्तन होता है i(नोट: वास्तव में यह अभी भी यह धारणा बनाता है जो iकभी नकारात्मक नहीं है)।

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


-1

मैं व्यक्तिगत रूप से 'मजबूत' के रूप में एक कोड का वर्णन करता हूं जिसमें यह एक है, महत्वपूर्ण विशेषताएं:

  1. अगर मेरी माँ उसके सामने बैठती है और उसके साथ काम करती है, तो वह सिस्टम को नहीं तोड़ सकती

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.