किसी पूर्णांक कोड को वापस करने वाले फ़ंक्शन का अनुक्रमण करना जो कई अलग-अलग स्थितियों का प्रतिनिधित्व करता है


10

मुझे कुछ भयानक कोड विरासत में मिले हैं जिन्हें मैंने नीचे दिया है।

  • क्या इस विशेष विरोधी पैटर्न का कोई नाम है?
  • इसे फिर से तैयार करने के लिए कुछ सिफारिशें क्या हैं?

    // 0=Need to log in / present username and password
    // 2=Already logged in
    // 3=Inactive User found
    // 4=Valid User found-establish their session
    // 5=Valid User found with password change needed-establish their session
    // 6=Invalid User based on app login
    // 7=Invalid User based on network login
    // 8=User is from an non-approved remote address
    // 9=User account is locked
    // 10=Next failed login, the user account will be locked
    
    public int processLogin(HttpServletRequest request, HttpServletResponse response, 
                            int pwChangeDays, ServletContext ServContext) { 
    }
    

2
क्या कर रहे हैं "में पाया स्थापित" और "जरूरत से स्थापित" ?
ट्यूलेंस कोर्डोवा

4
इसे एक एम डैश माना जाता है , "मान्य उपयोगकर्ता मिला: अपना सत्र स्थापित करें" जैसे पढ़ें।
बीजे मायर्स

2
@A_B उन रिटर्न मानों में से कौन सा सफल लॉगिन है जो विफल लॉगिन हैं। सभी स्वयं स्पष्ट नहीं हैं।
तुलसी कोर्डोवा

@A_B क्या "सत्र की स्थापना" का अर्थ है "सत्र स्थगित हो गया" या "सत्र की स्थापना करने की आवश्यकता है"?
ट्यूलेंस कोर्डोवा

@ TulainsCórdova: "स्थापना" का अर्थ है "बनाने के लिए" (इस संदर्भ में कम से कम) - तो "सत्र की स्थापना" लगभग "सत्र बनाने के लिए" के बराबर है
हॉफमेल

जवाबों:


22

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

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

public LoginResult processLogin(HttpServletRequest request, HttpServletResponse response, 
                            int pwChangeDays, ServletContext ServContext) { 
    }

==> LoginResult.java <==

public enum LoginResult {
    NOT_LOGGED_IN(Severity.DENIAL),
    ALREADY_LOGGED_IN(Severity.PASS),
    INACTIVE_USER(Severity.DENIAL),
    VALID_USER(Severity.PASS),
    NEEDS_PASSWORD_CHANGE(Severity.WAIVER),
    INVALID_APP_USER(Severity.DENIAL),
    INVALID_NETWORK_USER(Severity.DENIAL),
    NON_APPROVED_ADDRESS(Severity.DENIAL),
    ACCOUNT_LOCKED(Severity.DENIAL),
    ACCOUNT_WILL_BE_LOCKED(Severity.WAIVER);

    private Severity severity;

    private LoginResult(Severity severity) {
        this.severity = severity;
    }

    public Severity getSeverity() {
        return this.severity;
    }
}

==> गंभीरता.जावा <==

public enum Severity {
    PASS,
    WAIVER,
    DENIAL;
}

==> टेस्ट.जावा <==

public class Test {

    public static void main(String[] args) {
        for (LoginResult r: LoginResult.values()){
            System.out.println(r + " " +r.getSeverity());           
        }
    }
}

प्रत्येक लॉगिन के लिए गंभीरता दिखाने वाले टेस्ट.जावा के लिए आउटपुट:

NOT_LOGGED_IN : DENIAL
ALREADY_LOGGED_IN : PASS
INACTIVE_USER : DENIAL
VALID_USER : PASS
NEEDS_PASSWORD_CHANGE : WAIVER
INVALID_APP_USER : DENIAL
INVALID_NETWORK_USER : DENIAL
NON_APPROVED_ADDRESS : DENIAL
ACCOUNT_LOCKED : DENIAL
ACCOUNT_WILL_BE_LOCKED : WAIVER

एनम मूल्य और इसकी गंभीरता दोनों के आधार पर, आप यह तय कर सकते हैं कि सत्र का निर्माण आगे बढ़ता है या नहीं।

संपादित करें:

@ T.Sar की टिप्पणी की प्रतिक्रिया के रूप में, मैंने (OK, WARNING और ERROR) के बजाय PASS, WAIVER और DENIAL के गंभीरता के संभावित मूल्यों को बदल दिया। इस तरह यह स्पष्ट है कि एक DENIAL (पहले ERROR) प्रति त्रुटि नहीं है और जरूरी नहीं कि अपवाद को फेंक दिया जाए। कॉलर ऑब्जेक्ट की जांच करता है और यह तय करता है कि अपवाद को फेंकना है या नहीं, लेकिन कॉल करने के परिणामस्वरूप DENIAL एक वैध परिणाम स्थिति है processLogin(...)

  • पास: आगे बढ़ो, अगर कोई पहले से मौजूद नहीं है तो एक सत्र बनाएं
  • WAIVER: इस बार आगे बढ़ें, लेकिन अगली बार उपयोगकर्ता को आपको पास करने की अनुमति नहीं दी जा सकती
  • डेनियल: क्षमा करें, उपयोगकर्ता पास नहीं कर सकता, सत्र न बनाएं

आप Enum में त्रुटि के स्तर को एम्बेड करने के लिए एक "जटिल" एनम (विशेषताओं के साथ एनम) का निर्माण कर सकते हैं। हालाँकि सावधान रहें क्योंकि यदि आप सोमे क्रमिक उपकरण का उपयोग करते हैं, तो वह बहुत अच्छी तरह से नहीं गुजर सकता है।
वल्फ्रैट

त्रुटि मामलों में अपवादों को फेंकना और केवल सफलता के लिए एनम को बचाना भी एक विकल्प है।
टी। सर

@ टी। एस। खैर, जैसा कि मैंने समझा कि वे किसी कारण से त्रुटि नहीं हैं, लेकिन किसी कारण से सत्र बनाने से इनकार करते हैं। मैं जवाब को संपादित करूंगा।
ट्यूलेंस कोरडोवा

@ T.Sar मैंने मानों को PASS, WAIVER और DENIAL में बदल दिया ताकि यह स्पष्ट हो सके कि जिसे मैंने पहले ERROR कहा था वह एक मान्य स्थिति है। हो सकता है कि अब मैं के लिए एक बेहतर नाम के साथ आने चाहिएSeverity
Tulains Córdova

मैं अपने सुझाव के साथ कुछ और सोच रहा था, लेकिन मुझे वास्तव में आपका सुझाव पसंद आया! मैं निश्चित रूप से एक +1 को फेंक रहा हूं!
टी। सर

15

यह आदिम जुनून का एक उदाहरण है - "सरल" कार्यों के लिए आदिम प्रकारों का उपयोग करना जो अंततः इतना सरल नहीं बनते।

यह कोड के रूप में शुरू हो सकता है जो boolसफलता या विफलता को इंगित करने के लिए वापस लौटा , फिर intजब तीसरी स्थिति थी , तब बदल गया और अंततः पूरी तरह से nigh-undocumented त्रुटि स्थितियों की सूची बन गई।

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

अधिक रिफैक्टिंग पैटर्न जो उपयोगी हो सकते हैं, के लिए इंडस्ट्रियल लॉजिक की महक से लेकर रिफलेक्टर्स चीटशीट तक पर एक नजर डाल सकते हैं ।


7

मुझे लगता है कि "मैजिक नंबरों" का मामला है - वे नंबर जो विशेष हैं और खुद से कोई स्पष्ट अर्थ नहीं रखते हैं।

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


यह आमतौर पर 'जादुई संख्या' के साथ नहीं है।
D ड्रमर

2
यह कॉल साइटों पर जादू की संख्या के रूप में दिखाई देगा, जैसे किif (processLogin(..) == 3)
डेन्थ

@Drmmr - यह वास्तव में 'मैजिक नंबर्स' कोड गंध का मतलब है। यह फ़ंक्शन हस्ताक्षर लगभग निश्चित रूप से बताता है कि प्रक्रियालोगिन () में "वापसी 8;" जैसी लाइनें शामिल हैं। इसके क्रियान्वयन में, और यह बहुत अधिक बलों कोड का उपयोग करते हुए processLogin () कुछ इस तरह दिखता है "अगर (resultFromProcessLogin == 7) {"।
स्टीफन सी। स्टील

3
@Stephen संख्याओं का वास्तविक मूल्य यहाँ अप्रासंगिक है। वे सिर्फ आईडी हैं। मैजिक नंबर शब्द आमतौर पर कोड में मान के लिए उपयोग किया जाता है जिसका एक अर्थ होता है, लेकिन जो का अर्थ अनिर्दिष्ट है (उदाहरण के लिए एक चर नाम में)। नामित पूर्णांक चर के साथ यहां मानों को प्रतिस्थापित करने से समस्या ठीक नहीं होगी।
D ड्रमर

2

यह कोड का एक विशेष रूप से अप्रिय सा है। एंटीपैटर्न को "मैजिक रिटर्न कोड" के रूप में जाना जाता है। आप यहां एक चर्चा पा सकते हैं ।

वापसी मानों में से कई त्रुटि राज्यों को इंगित करते हैं। फ्लो कंट्रोल के लिए एरर हैंडलिंग का उपयोग करना है या नहीं इस पर एक वैध बहस है , लेकिन मुझे लगता है कि 3 मामले हैं: सफलता (कोड 4), सफलता लेकिन पासवर्ड (कोड 5) बदलने की आवश्यकता है, और "अनुमति नहीं है"। इसलिए, यदि आपको प्रवाह नियंत्रण के अपवादों का उपयोग करने की परवाह नहीं है, तो आप उन राज्यों को इंगित करने के लिए अपवादों का उपयोग कर सकते हैं।

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

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