बूलियन के बहुत सारे गुणों के साथ एनम


11

मैं वर्तमान में एक वेबएप पर काम कर रहा हूं, जहां हमें अक्सर उस पेज के आधार पर कुछ सर्वर लॉजिक को कंडीशन करने की आवश्यकता होती है जो उपयोगकर्ता को वापस करने जा रहे हैं।

प्रत्येक पृष्ठ को 4-अक्षर का पृष्ठ कोड दिया जाता है, और ये पृष्ठ कोड वर्तमान में स्थिर स्ट्रिंग्स के रूप में एक वर्ग में सूचीबद्ध होते हैं:

public class PageCodes {
    public static final String FOFP = "FOFP";
    public static final String FOMS = "FOMS";
    public static final String BKGD = "BKGD";
    public static final String ITCO = "ITCO";
    public static final String PURF = "PURF";
    // etc..
}

और अक्सर कोड में हम कोड को इस तरह से देखते हैं ( प्रथम रूप ):

if (PageCode.PURF.equals(destinationPageCode) || PageCodes.ITCO.equals(destinationPageCode)) {
    // some code with no obvious intent
} 
if (PageCode.FOFP.equals(destinationPageCode) || PageCodes.FOMS.equals(destinationPageCode)) {
    // some other code with no obvious intent either
} 

यह पढ़ने के लिए किस तरह का भयानक है क्योंकि यह नहीं दिखाता है कि इन पृष्ठों की आम संपत्ति ने उन्हें एक साथ रखने के लिए कोड के लेखक का नेतृत्व किया। हमें ifसमझने के लिए शाखा में कोड पढ़ना होगा ।

वर्तमान समाधान

ये ifउन पृष्ठों की सूची का उपयोग करके आंशिक रूप से सरल किए गए हैं जो विभिन्न वर्गों में विभिन्न लोगों द्वारा घोषित किए गए हैं। यह कोड जैसा दिखता है ( दूसरा रूप ):

private static final List<String> pagesWithShoppingCart = Collections.unmodifiableList(Arrays.asList(PageCodes.ITCO, PageCodes.PURF));
private static final List<String> flightAvailabilityPages = Collections.unmodifiableList(Arrays.asList(PageCodes.FOMS, PageCodes.FOFP));

// later in the same class
if (pagesWithShoppingCart.contains(destinationPageCode)) {
    // some code with no obvious intent
} 
if (flightAvailabilityPages.contains(destinationPageCode)) {
    // some other code with no obvious intent either
} 

... जो इरादे को बहुत बेहतर व्यक्त करता है। परंतु...

वर्तमान समस्या

यहां समस्या यह है कि यदि हम एक पृष्ठ जोड़ते हैं, तो हमें यह जानने के लिए कि क्या हमें अपने पृष्ठ को एक if()या एक सूची में जोड़ने की आवश्यकता है, यह जानने के लिए सभी कोड आधार से गुजरना होगा ।

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

नया समाधान

मेरा समाधान एक एनम बनाने के लिए था (क्योंकि पेज कोड की एक अच्छी तरह से ज्ञात सूची है) जहां प्रत्येक पृष्ठ में कुछ गुण होते हैं जिन्हें हमें सेट करने की आवश्यकता होती है:

public enum Page {
    FOFP(true, false),
    FOMS(true, false),
    BKGD(false, false),
    PURF(false, true),
    ITCO(false, true),
    // and so on

    private final boolean isAvailabilityPage;
    private final boolean hasShoppingCart;

    PageCode(boolean isAvailabilityPage, boolean hasShoppingCart) {
        // field initialization
    }

    // getters
}

तब सशर्त कोड अब इस तरह दिखता है ( तीसरा रूप ):

if (destinationPage.hasShoppingCart()) {
    // add some shopping-cart-related data to the response
}
if (destinationPage.isAvailabilityPage()) {
    // add some info related to flight availability
}

जो बहुत पठनीय है। इसके अलावा, अगर किसी को एक पृष्ठ जोड़ने की जरूरत है, तो उसे प्रत्येक बूलियन के बारे में सोचने के लिए मजबूर किया जाता है और क्या यह उसके नए पृष्ठ के लिए सही या गलत है।

नई समस्या

एक समस्या जो मैं देख रहा हूं वह यह है कि इस तरह के 10 बूलियन हो सकते हैं, जो निर्माणकर्ता को वास्तव में बड़ा बनाता है और जब आप एक पृष्ठ जोड़ते हैं तो घोषणा को प्राप्त करना कठिन हो सकता है। क्या किसी के पास बेहतर उपाय है?

जवाबों:


13

आप विचार को एक कदम आगे ले जा सकते हैं और बूलियन्स का उपयोग करने के बजाय अपने पृष्ठ सुविधाओं के लिए एक दुश्मनी को परिभाषित कर सकते हैं।

इससे किसी फीचर को पेज में जोड़ना / हटाना आसान हो जाता है और 30-40 संभावित फीचर्स होने पर भी पेज की परिभाषा तुरंत पढ़ने योग्य हो जाती है।

public enum PageFeature {
    AVAIL_PAGE,
    SHOPPING_CART;
}

public enum Page {
    FOFP(AVAIL_PAGE),
    FOMS(AVAIL_PAGE),
    BKGD(),
    PURF(SHOPPING_CART, AVAIL_PAGE),

    private final EnumSet<PageFeature> features;

    PageCode(PageFeature ... features) {
       this.features = EnumSet.copyOf(Arrays.asList(features));
    }

    public boolean hasFeature(PageFeature feature) {
       return features.contains(feature);
    }
 }

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

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

ठीक है, मैंने इसके बारे में इस तरह से नहीं सोचा था :) और मुझे नहीं लगता कि बूलियन द्वारा दिए गए छोटे अतिरिक्त "मूर्खतापूर्ण प्रमाण" की स्थिति में गिरावट के लायक है, इसलिए मैं शायद वैरग समाधान के साथ जाऊंगा। आपकी अंतर्दृष्टि के लिए धन्यवाद!
जॉफ्रे

1
अच्छा समाधान, उत्थान। हालांकि मुझे का हिस्सा है कि 6502s पर कोडित बिट्स में सब कुछ रटना चाहता है। :-)
user949300

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