我继承了一个java应用程序,它处理请求并在确定应该取消请求时抛出异常。对于以前的开发人员来说,例外是很方便的,因为它们是退出不再适用的逻辑树的简单方法(是一个goto),并且它会向日志打印一个堆栈跟踪,这是一个很好的信息。似乎是论坛和博客上的共识,不应将异常用于流量控制,并且超过一半的处理请求被取消,因此它们绝对不是例外情况。一个参数是性能,它不适用,因为我们的异常代码运行速度足够多年。另一个论点是,它的结果尚不清楚,我同意这一点。我的问题是:替代方案是什么。我唯一能想到的是,如果处理应该继续,则每个方法都返回true,否则返回false。这似乎会使我的代码变得非常膨胀:
checkSomething();
checkSomethingElse();
进入这个:
boolean continueProcessing = false;
continueProcessing = checkSomething();
if (!continueProcessing) {
return false;
}
continueProcessing = checkSomethingElse();
if (!continueProcessing) {
return false;
}
然后如果该方法应该返回什么呢?任何指导都会很棒。我真的很想观察可用的“最佳实践”。
更新
我可能首先应该提到的另一个问题是,请求在超过50%的时间内被取消,并不意味着某些事情没有正确,这意味着毕竟不需要请求。 / p>
答案 0 :(得分:5)
在您的方案中,替代方案是抛出异常并返回结果。
哪个最好(哪个是“最佳实践”)取决于“检查...”方法的失败是否应归类为正常或异常。在某种程度上,这是一个你必须做出的判断。在打电话时,有几件事要记住:
创建+投掷+捕获异常大约比测试布尔结果低3个数量级。
返回状态代码的一个大问题是很容易忘记测试它们。
总之,最佳做法是不使用异常来实现普通流量控制,但由您自行决定 normal 和之间的边界线特殊的是。
在没有看到真实的代码/上下文的情况下,我的直觉是这可能是使用异常的合适位置。
答案 1 :(得分:4)
有关此主题的详细讨论,请参阅How slow are Java exceptions?。
答案 2 :(得分:1)
TL;博士
分离关注,IMO你应该这样做:
continue = checkSomething() && checkSomethingElse();
或者代码中可能存在其他设计问题。
该功能的关注点 - 您想要定义它(这可能是一个主观问题)? 如果错误符合函数的关注点,则不要抛出异常。如果你对错误是否符合问题感到困惑,那么函数可能试图自己完成太多的关注(糟糕的设计)。
错误控制选项:
如果代码的目的是检查某个状态,那么知道状态为false就是直接函数的点。不要抛出异常,但返回false。
这就是你想要的样子。您有正在运行检查程序Y和Z的进程X.进程X(或任何调用进程)的控制流与不与检查系统状态相同。
答案 3 :(得分:0)
int error = 0;
do
{//try-alt
error = operation_1(); if(error > 0){break;}
error = operation_2(); if(error > 0){break;}
error = operation_3(); if(error > 0){break;}
}while(false);
switch(error) //catch-alt
{
case 1: handle(1); break;
case 2: handle(2); break;
case 3: handle(3); break;
}
答案 4 :(得分:-1)
怎么样
if (!checkSomething()) return false;
if (!checkSomethingElse()) return false;
如果您提前退出,则无需使用该标志。