java - मैं कई बयानों के साथ एक पठनीयता और विधि की लंबाई कैसे सुधार सकता हूं?




design-patterns (4)

एक Map<String,Double> बनाएं Map<String,Double> जो नक्शे देश के नाम उनकी संबंधित कर दरों के लिए बनाते हैं:

Map<String,Double> taxRates = new HashMap<> ();
taxRates.put("POLAND",0.23);
...

निम्नानुसार उस Map उपयोग करें:

private BigDecimal calculateTax(String country, BigDecimal amount) throws Exception {
    if (taxRates.containsKey(country)) {
        return new BigDecimal(taxRates.get(country)).multiply(amount);
    } else {
        throw new Exception("Country not supported");
    }
}

मेरे पास 195 के साथ एक विधि है यदि। यहाँ एक छोटा संस्करण है:

private BigDecimal calculateTax(String country, BigDecimal amount) throws Exception {
    if(country.equals("POLAND")){
        return new BigDecimal(0.23).multiply(amount);
    }
    else if(country.equals("AUSTRIA")) {
        return new BigDecimal(0.20).multiply(amount);
    }
    else if(country.equals("CYPRUS")) {
        return new BigDecimal(0.19).multiply(amount);
    }
    else {
        throw new Exception("Country not supported");
    }
}

मैं बदल सकता हूँ अगर स्विच करने के लिए:

private BigDecimal calculateTax(String country, BigDecimal amount) throws Exception {
    switch (country) {
        case "POLAND":
            return new BigDecimal(0.23).multiply(amount);
        case "AUSTRIA":
            return new BigDecimal(0.20).multiply(amount);
        case "CYPRUS":
            return new BigDecimal(0.19).multiply(amount);
        default:
            throw new Exception("Country not supported");
    }
}

लेकिन 195 मामले अभी भी इतने लंबे हैं। मैं उस विधि की पठनीयता और लंबाई कैसे सुधार सकता हूं? इस मामले में कौन सा पैटर्न सबसे अच्छा होगा?


एक फ्रेम चुनौती के रूप में ...

195 मामले बहुत लंबे नहीं हैं अगर यह स्पष्ट है कि वे क्या कर रहे हैं और क्यों, और यदि प्रत्येक मामले के अंदर कोड न्यूनतम है। हां यह लंबा है, लेकिन यह पूरी तरह से पठनीय है क्योंकि आप जानते हैं कि वास्तव में यह क्या कर रहा है। लंबाई जरूरी नहीं कि अप्राप्य हो।

जैसा कि अन्य उत्तरों में कहा गया है, यह एक कोड गंध हो सकता है जो यह दर्शाता है कि आप OO का ठीक से उपयोग नहीं कर रहे हैं। लेकिन अपने दम पर, यह सिर्फ लंबा है, अपठनीय नहीं है।


यदि मान स्थिर हैं और नियमित रूप से बदले जाने के लिए नहीं हैं (जो मुझे संदेह है)। मैं Enum का उपयोग करके एक स्थिर मेटामॉडल पेश करूँगा:

public enum CountryList {

    AUSTRIA(BigDecimal.valueOf(0.20)),
    CYPRUS(BigDecimal.valueOf(0.19)),
    POLAND(BigDecimal.valueOf(0.23));

    private final BigDecimal countryTax;

    CountryList(BigDecimal countryTax) {
        this.countryTax = countryTax;
    }

    public BigDecimal getCountryTax() {
        return countryTax;
    }

    public static BigDecimal countryTaxOf(String countryName) {
        CountryList country = Arrays.stream(CountryList.values())
                .filter(c -> c.name().equalsIgnoreCase(countryName))
                .findAny()
                .orElseThrow(() -> new IllegalArgumentException("Country is not found in the dictionary: " + countryName));

        return country.getCountryTax();
    }
}

फिर

private BigDecimal calculateTax(String country, BigDecimal amount) throws Exception {
    return CountryList.countryTaxOf(country).multiply(amount);
}

यह पठनीय है, संकलन समय सुरक्षित है, प्रति देश और अतिरिक्त बॉयलरप्लेट के साथ आसानी से विस्तार योग्य है।


EDIT: @ अलेक्जेंडर का जवाब याद किया; यह थोड़ा अधिक हो सकता है, लेकिन वह मुख्य बिंदु को भी मार रहा है: OOP का उपयोग करें।
EDIT 2: @ लुआना के सुझावों को लागू किया

मैं शायद कुछ स्पष्ट याद कर रहा हूं, और इस देर से एक मंच पर लागू करना थोड़ा मुश्किल हो सकता है, लेकिन यह मुझे ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग के लिए एक आदर्श मामले की तरह लगता है:

आप एक ऐसा Country वर्ग बनाते हैं, जिसमें किसी देश से जुड़ी हर चीज़ होती है, जैसे कि एक name और एक calculateTax() विधि और व्हाट्सएप, और फिर आपका कॉलर ( calculateTotalAmount() या जो भी हो) calculateTax(country, amount) बजाय country.calculateTax(amount) को कॉल करेगा calculateTax(country, amount) , और पूरा / स्विच निर्माण अभी चला गया है।

इसके अलावा, जब आप एक नए देश के लिए समर्थन जोड़ते हैं (कहते हैं, वहाँ एक और गृहयुद्ध है और एक देश अलग हो जाता है), तो आप बस नए देश के लिए एक एकल स्थान पर एक विशाल स्थान पर शिकार करने के बजाय सब कुछ जोड़ते हैं if() चेन या switch() तों ...





design-patterns