Есть ли способ сократить условие, содержащее кучу булевых сравнений? - PullRequest
3 голосов
/ 07 марта 2011

например

if("viewCategoryTree".equals(actionDetail)
                || "fromCut".equals(actionDetail)
                || "fromPaste".equals(actionDetail)
                || ("viewVendorCategory".equals(actionDetail))&&"viewCategoryTree".equals(vendorCategoryListForm.getActionOrigin())
                || ("viewVendorCategory".equals(actionDetail))&&"fromEdit".equals(vendorCategoryListForm.getActionOrigin())
                || "deleteSelectedItem".equals(actionDetail)
                || ("viewVendorCategory".equals(actionDetail))&&"fromLink".equals(vendorCategoryListForm.getActionOrigin())){
//do smth
}

Я пробовал что-то вроде этого

if(check("deleteSelectedItem,viewCategoryTree,fromCut,fromPaste,{viewVendorCategory&&viewVendorCategory},{viewVendorCategory&&fromEdit},{viewVendorCategory&&fromLink}",actionDetail,actionOrigin)){
//do smth
}

public boolean check(String str, String ad, String ao){

    String oneCmp = "";
    String[] result = str.split(",");
    ArrayList adList = new ArrayList();
    ArrayList aoList = new ArrayList();
    for (int i=0; i<result.length; i++){
        oneCmp = result[i];
        Matcher m = Pattern.compile("\\{([^}]*)\\}").matcher(oneCmp);
        if(m.matches()){
            m.find();
            String agrp = m.group();
            String[] groupresult = agrp.split("[\\W&&[^!]]+");
            Boolean a = false;
            Boolean b = false;
            if(groupresult[0].startsWith("!")){
                a = !groupresult[0].substring(1).equals(ad);
            } else a = groupresult[0].equals(ad);
            if(groupresult[1].startsWith("!")){
                b = !groupresult[1].substring(1).equals(ao);
            }else b = groupresult[1].equals(ao);

            if(agrp.indexOf("&&")!=-1){
                if(!(a && b))return false;
            }
            else if(agrp.indexOf("||")!=-1){
                if(!(a || b))return false;
            }
        } else {
            if(oneCmp.indexOf("^")==-1){
                checklist(oneCmp,ad);
                        if(!checklist(oneCmp,ad))return false;
            }else{
            if(!checklist(oneCmp,ao))return false;
            }
        }
    }

    return false;
}

public boolean checklist(String str, String key){

    if(str.startsWith("!")){
        if(str.substring(1).equals(key))return false;
        }else { if (!str.substring(1).equals(key)) return false;
        }
    }

    return false;
}

есть ли лучший способ сделать это? спасибо.

Ответы [ 6 ]

2 голосов
/ 07 марта 2011

Как насчет создания массива того, с чем вам нужно протестировать.И еще такой код:

arrayOfStrings = ["viewCategoryTree", ...]
match = false
for elem in arrayOfStrings:
   if elem == actionDetail:
       match = true
       break

Преимущество массива в том, что он легко расширяемый: вы можете легко добавлять / удалять элементы как статически, так и динамически.

2 голосов
/ 07 марта 2011

Переместите проверку в метод, который принимает actionDetail в качестве аргумента:

// Assumes vendorCategoryListForm is a member variable.
boolean check(String actionDetail) {
    return ("viewCategoryTree".equals(actionDetail)
            || "fromCut".equals(actionDetail)
            || "fromPaste".equals(actionDetail)
            || (("viewVendorCategory".equals(actionDetail))
                &&"viewCategoryTree".equals(vendorCategoryListForm.getActionOrigin()))
            || (("viewVendorCategory".equals(actionDetail))
                &&"fromEdit".equals(vendorCategoryListForm.getActionOrigin()))
            || "deleteSelectedItem".equals(actionDetail)
            || (("viewVendorCategory".equals(actionDetail))
                &&"fromLink".equals(vendorCategoryListForm.getActionOrigin())))
}

if (check(actionDetail)) {
    // do this
}
1 голос
/ 07 марта 2011

Также просим вас посмотреть этот пост

Язык не распознает Кредиты на гальванический

См. Свод кода стрелки для получения справки.

   1. Replace conditions with guard clauses.
   2. Decompose conditional blocks into seperate functions.
   3. Convert negative checks into positive checks.
0 голосов
/ 07 марта 2011
if(isValidActionDetail(actionDetail)
            || (isValidActionDetail(actionDetail)
            && ("viewCategoryTree".equals(vendorCategoryListForm.getActionOrigin()) 
                || "fromEdit".equals(vendorCategoryListForm.getActionOrigin())  
                || "fromLink".equals(vendorCategoryListForm.getActionOrigin())))){

//do smth
    }
}

public static boolean isValidActionDetail (String actionDetail) {
    return "viewCategoryTree".equals(actionDetail) || "fromCut".equals(actionDetail) 
           || "fromPaste".equals(actionDetail) || "deleteSelectedItem".equals(actionDetail) 
           || "viewVendorCategory".equals(actionDetail);
}

Вы можете разложить вышеуказанным способом, как первый шаг к рефакторингу вашей логики.

0 голосов
/ 07 марта 2011

Я не думаю, что вы собираетесь улучшить это без добавления сложностей, как с точки зрения обозначения, которое вы используете для выражения условий, так и реализации «движка», который их оценивает.

Проблема нотации заключается в том, что: хотя вы можете в конечном итоге выразить условия меньшим количеством символов, кто-то другой, читающий ваш код, должен выяснить, что на самом деле означает этот литеральный строковый литерал.

Кроме того, все, что вы делаете умноможет оказать влияние на производительность.Например, ваша попытка компилируется и применяет регулярное выражение несколько раз для каждого вызова на check.

. Следуйте моим советам.

0 голосов
/ 07 марта 2011

Честно говоря, этот код больше не читается. Я бы лучше предложил инкапсулировать эту условную проверку в некоторое свойство для типа, подобного if (control.IsApplicable) { // do smth }.

Неважно, параметризованы ли вы одним или двумя аргументами. Но я полагаю, что лучшее решение состоит в том, чтобы иметь массив совпадений, с которыми можно было бы проверить, и если сопоставить, вернуть true.

...