【问题标题】:Is there a way to shorten a conditional that contains a bunch of boolean comparisons?有没有办法缩短包含一堆布尔比较的条件?
【发布时间】:2011-03-07 04:21:43
【问题描述】:

例如

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;
}

有没有更好的方法来做到这一点?谢谢。

【问题讨论】:

  • 你可以使用某种“包含”或“输入”功能吗?
  • 你应该在codereview.stackexchange.com问这个问题
  • @Oscar 他可以问这个问题,但这里仍然是主题。
  • @Will 看看 Jeff 的回答:meta.stackexchange.com/questions/82069/…
  • @Oscar 老实说,问题不在于“这是我的代码,是好是坏”,而是缩短包含 lots 布尔比较的 if 语句的技术。它的模式多于实践。它绝对是这里的主题,并且可能会在 codereview.SE 上被考虑。

标签: java regex string compare tokenize


【解决方案1】:

将检查移至以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
}

【讨论】:

    【解决方案2】:

    如何创建一个您需要测试的数组。 然后是这样的一些代码:

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

    数组的好处是它易于扩展:您可以轻松地静态和动态地添加/删除元素。

    【讨论】:

      【解决方案3】:

      也请看这篇文章

      Language Agnostic 感谢 Galwegian

      请参阅Flattening Arrow Code 寻求帮助。

         1. Replace conditions with guard clauses.
         2. Decompose conditional blocks into seperate functions.
         3. Convert negative checks into positive checks.
      

      【讨论】:

        【解决方案4】:

        老实说,该代码不再具有可读性。我最好建议将该条件检查封装到 if (control.IsApplicable) { // do smth } 之类的某些属性中。

        无论您使用一个或两个参数进行参数化。 但我想更好的解决方案是有一个可以测试的匹配数组,如果匹配则返回 true。

        【讨论】:

          【解决方案5】:

          我不认为你会在不增加一堆复杂性的情况下改进这一点,无论是在你用来表达条件的符号和评估它们的“引擎”的实现方面。

          符号问题在于:虽然您最终可能会用更少的字符来表达条件,但阅读您的代码的其他人必须弄清楚那个时髦的字符串文字的真正含义。

          此外,您所做的任何聪明的事情都可能对性能产生影响。例如,您的尝试为每次调用 check 编译并多次应用正则表达式。

          我的建议是坚持你所拥有的。

          【讨论】:

            【解决方案6】:
            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);
            }
            

            您可以按照上述方式进行分解,作为重构逻辑的第一步。

            【讨论】:

              猜你喜欢
              • 2020-06-25
              • 1970-01-01
              • 2019-12-01
              • 1970-01-01
              • 2014-07-28
              • 1970-01-01
              • 1970-01-01
              • 2022-11-18
              相关资源
              最近更新 更多