जब मैं एक विशिष्ट कार्यक्रम के लिए एक इंटरफ़ेस बनाने की कोशिश कर रहा हूं तो मैं आमतौर पर अपवादों को फेंकने से बचने की कोशिश कर रहा हूं जो गैर-मान्य इनपुट पर निर्भर करता है।
तो अक्सर ऐसा होता है कि मैंने इस तरह के कोड का एक टुकड़ा सोचा है (यह एक उदाहरण के लिए सिर्फ एक उदाहरण है, यह जो कार्य करता है उसे ध्यान में न रखें, जावा में उदाहरण है):
public static String padToEvenOriginal(int evenSize, String string) {
if (evenSize % 2 == 1) {
throw new IllegalArgumentException("evenSize argument is not even");
}
if (string.length() >= evenSize) {
return string;
}
StringBuilder sb = new StringBuilder(evenSize);
sb.append(string);
for (int i = string.length(); i < evenSize; i++) {
sb.append(' ');
}
return sb.toString();
}
ठीक है, इसलिए कहते हैं कि evenSize
वास्तव में उपयोगकर्ता इनपुट से लिया गया है। तो मुझे यकीन नहीं है कि यह भी है लेकिन मैं इस पद्धति को इस संभावना के साथ नहीं बुलाना चाहता कि कोई अपवाद फेंका जाए। इसलिए मैं निम्नलिखित कार्य करता हूं:
public static boolean isEven(int evenSize) {
return evenSize % 2 == 0;
}
लेकिन अब मुझे दो चेक मिले हैं जो समान इनपुट सत्यापन करते हैं: if
कथन में अभिव्यक्ति और स्पष्ट चेक इन isEven
। डुप्लिकेट कोड, अच्छा नहीं है, तो आइए रिफ्लेक्टर:
public static String padToEvenWithIsEven(int evenSize, String string) {
if (!isEven(evenSize)) { // to avoid duplicate code
throw new IllegalArgumentException("evenSize argument is not even");
}
if (string.length() >= evenSize) {
return string;
}
StringBuilder sb = new StringBuilder(evenSize);
sb.append(string);
for (int i = string.length(); i < evenSize; i++) {
sb.append(' ');
}
return sb.toString();
}
ठीक है, कि इसे हल कर दिया, लेकिन अब हम निम्नलिखित स्थिति में आते हैं:
String test = "123";
int size;
do {
size = getSizeFromInput();
} while (!isEven(size)); // checks if it is even
String evenTest = padToEvenWithIsEven(size, test);
System.out.println(evenTest); // checks if it is even (redundant)
अब हमें एक निरर्थक जांच मिल गई है: हम पहले से ही जानते हैं कि मूल्य सम है, लेकिन फिर padToEvenWithIsEven
भी पैरामीटर चेक करता है, जो हमेशा सही रहेगा, जैसा कि हमने पहले ही इस फ़ंक्शन को कहा था।
अब isEven
बेशक इसके लिए कोई समस्या नहीं है, लेकिन यदि पैरामीटर जाँच अधिक बोझिल है तो इससे बहुत अधिक लागत आ सकती है। इसके अलावा, एक निरर्थक कॉल का प्रदर्शन बस सही नहीं लगता है।
कभी-कभी हम "मान्य प्रकार" की शुरुआत करके या एक फ़ंक्शन बनाकर काम कर सकते हैं जहां यह समस्या नहीं हो सकती है:
public static String padToEvenSmarter(int numberOfBigrams, String string) {
int size = numberOfBigrams * 2;
if (string.length() >= size) {
return string;
}
StringBuilder sb = new StringBuilder(size);
sb.append(string);
for (int i = string.length(); i < size; i++) {
sb.append('x');
}
return sb.toString();
}
लेकिन इसके लिए कुछ स्मार्ट सोच और काफी बड़े रिफ्लेक्टर की जरूरत होती है।
क्या ऐसा (अधिक) सामान्य तरीका है जिसमें हम isEven
दोहरा पैरामीटर जाँच करने और करने के लिए अनावश्यक कॉल से बच सकते हैं ? मैं चाहता हूं कि समाधान वास्तव padToEven
में एक अवैध पैरामीटर के साथ कॉल न करे , अपवाद को ट्रिगर करता है।
बिना किसी अपवाद के मुझे अपवाद-मुक्त प्रोग्रामिंग से मतलब नहीं है, मेरा मतलब है कि उपयोगकर्ता इनपुट डिज़ाइन द्वारा अपवाद को ट्रिगर नहीं करता है, जबकि सामान्य फ़ंक्शन में अभी भी पैरामीटर चेक होता है (यदि बस प्रोग्रामिंग त्रुटियों से बचाने के लिए)।
padToEvenWithIsEven
नहीं करता है । यह कॉलिंग में प्रोग्रामिंग त्रुटियों के खिलाफ खुद को बचाने के लिए अपने इनपुट पर एक वैधता जांच करता है । इस सत्यापन को कितना व्यापक होना चाहिए, यह एक लागत / जोखिम विश्लेषण पर निर्भर करता है, जहां आप चेक की लागत उस जोखिम के विरुद्ध डालते हैं जिसे कॉलिंग कोड लिखने वाला व्यक्ति गलत पैरामीटर में पास करता है।