需要嵌套条件的设计建议

时间:2017-01-19 19:33:07

标签: java

我需要在一组规则中编写具有许多条件(最多30个条件)的逻辑,其中包含许多if else条件,并且它可以在所有条件之间或之后结束。

以下是我尝试过的一些可能情况的示例代码。这给了我结果,但看起来并不好,在一种情况下任何轻微的失误都需要永远跟踪。

到目前为止我所尝试的是,找出共同的条件并重构一些方法。尝试创建具有条件和各种集合的接口将实现它。

如果您有任何建议来设计,请帮助我。不寻找详细的解决方案,但即使是暗示也会很棒。

private Boolean RunCondition(Input input) {
    Boolean ret=false;
    //First if
    if(input.a.equals("v1")){
        //Somelogic1();
        //Second if
        if(input.b.equals("v2"))
            //Third if
            if(input.c >1)
                //Fourth if
                //Somelogic2();
                //Go fetch key Z1 from database and see if d matches.
                if(input.d.equals("Z1"))                        
                        System.out.println("Passed 1");
                    // Fourth Else
                    else{
                        System.out.println("Failed at fourth");
                    }

            //Third Else
            else{
                if(input.aa.equals("v2"))
                    System.out.println("Failed at third");
                }
        //Second Else
        else{
            if(input.bb.equals("v2"))
                System.out.println("Failed at second");
            }
    }
    //First Else
    else{
        if(input.cc.equals("v2"))
            System.out.println("Failed aat first");
        }

    return ret;
}

public class Input {
    String a;
    String b;
    int c;
    String d;
    String e;       
    String aa;
    String bb;
    String cc;
    String dd;
    String ee;  

}

4 个答案:

答案 0 :(得分:1)

流程很复杂,因为你有一个正常的流程,加上许多可能的异常流程,当一些值是例外的(例如无效)时。

这是使用 try / catch / finally 块处理的完美候选者。

您的程序可以重写为以下内容:

private Boolean RunCondition(Input input) {
    Boolean ret=false;
    try {
        //First if
        if(!input.a.equals("v1")) {
            throw new ValidationException("Failed aat first");
        }
        //Somelogic1();

        //Second if
        if(!input.b.equals("v2")) {
            throw new ValidationException("Failed at second");
        }
        //Somelogic2()

        //Third if
        if(input.c<=1) {
            throw new ValidationException("Failed at third");
        } 

        //Fourth if
        //Somelogic2();
        //Go fetch key Z1 from database and see if d matches.
        if(!input.d.equals("Z1")) {
            throw new ValidationException("Failed at fourth");
        }
        System.out.println("Passed 1");

    } catch (ValidationException e) {
            System.out.println(e.getMessage());
    }

    return ret;
}

您可以在哪里定义自己的ValidationException(如下所示),或者您可以重复使用某些现有标准例外,例如RuntimeException

class ValidationException extends RuntimeException {

    public ValidationException(String arg0) {
        super(arg0);
        // TODO Auto-generated constructor stub
    }

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

}

您可以在

中详细了解此信息

https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html

答案 1 :(得分:1)

为条件单独创建一个类:

app.get('/', function(req, res){
   res.render("../yourpaste/index"); //the new index.ejs file
        });

答案 2 :(得分:1)

将每个规则检查视为一个对象,或者将其视为一个返回规则是否通过的策略。每个检查应实现相同的IRuleCheck接口并返回RuleCheckResult,它指示检查是否通过或失败的原因。

public interface IRuleCheck
{
   public RuleCheckResult Check(Input input);
   public String Name();
 }

public class RuleCheckResult
{
    private String _errorMessage;
    public RuleCheckResult(){}//All Good
    public RuleCheckResult(String errorMessage)
    {
         _errorMessage = errorMessage;
    }
    public string ErrorMessage()
    {
         return _errorMessage;
    }
    public Boolean Passed()
    {
       return _errorMessage == null || _errorMessage.isEmpty();
    }

}

public class CheckOne implements IRuleCheck
{
       public RuleCheckResult Check(Input input)
       {
          if (input.d.equals("Z1"))
          {
             return new RuleCheckResult();//passed
          }
          return new RuleCheckResult("d did not equal z1");
        }
       public String Name();
}

然后你可以简单地建立一个规则列表并循环遍历它们, 当一个失败时跳出或者编译一个失败列表。

for (IRuleCheck check : checkList) 
{
    System.out.println("checking: " + check.Name());
    RuleCheckResult result = check.Check(input);
    if(!result.Passed())
    {
        System.out.println("FAILED: " + check.Name()+ " - " + result.ErrorMessage());
       //either jump out and return result or add it to failure list to return later.
    }
}

使用界面的优点是支票可以根据需要复杂或简单,您可以创建任意列表以按任意顺序检查任何规则组合。

答案 3 :(得分:1)

@leeyuiwah's answer具有明确的条件逻辑结构,但例外不适合这里的工作。

您不应该使用例外来应对非例外情况。首先,构造异常非常昂贵,因为你必须一直走在调用堆栈的前面来构建堆栈跟踪;但你根本不需要堆栈跟踪。

查看 Effective Java 2nd Ed 项目57:“仅针对特殊情况使用例外”,详细讨论不应使用此类例外的原因。

更简单的选择是定义一个小帮助方法:

private static boolean printAndReturnFalse(String message) {
  System.out.println(message);
  return false;
}

然后:

if(!input.a.equals("v1")) {
  return printAndReturnFalse("Failed aat first");
}
// etc.
我认为这更简单;它会快得多。