什么是流量控制异常的替代方案?

时间:2011-04-26 23:46:50

标签: java exception-handling

我继承了一个java应用程序,它处理请求并在确定应该取消请求时抛出异常。对于以前的开发人员来说,例外是很方便的,因为它们是退出不再适用的逻辑树的简单方法(是一个goto),并且它会向日志打印一个堆栈跟踪,这是一个很好的信息。似乎是论坛和博客上的共识,不应将异常用于流量控制,并且超过一半的处理请求被取消,因此它们绝对不是例外情况。一个参数是性能,它不适用,因为我们的异常代码运行速度足够多年。另一个论点是,它的结果尚不清楚,我同意这一点。我的问题是:替代方案是什么。我唯一能想到的是,如果处理应该继续,则每个方法都返回true,否则返回false。这似乎会使我的代码变得非常膨胀:

checkSomething();
checkSomethingElse();

进入这个:

boolean continueProcessing = false;
continueProcessing = checkSomething();
if (!continueProcessing) {
    return false;
}
continueProcessing = checkSomethingElse();
if (!continueProcessing) {
    return false;
}

然后如果该方法应该返回什么呢?任何指导都会很棒。我真的很想观察可用的“最佳实践”。

更新

我可能首先应该提到的另一个问题是,请求在超过50%的时间内被取消,并不意味着某些事情没有正确,这意味着毕竟不需要请求。 / p>

5 个答案:

答案 0 :(得分:5)

在您的方案中,替代方案是抛出异常并返回结果。

哪个最好(哪个是“最佳实践”)取决于“检查...”方法的失败是否应归类为正常或异常。在某种程度上,这是一个必须做出的判断。在打电话时,有几件事要记住:

  • 创建+投掷+捕获异常大约比测试布尔结果低3个数量级。

  • 返回状态代码的一个大问题是很容易忘记测试它们。

总之,最佳做法是不使用异常来实现普通流量控制,但由您自行决定 normal 之间的边界线特殊的是。


在没有看到真实的代码/上下文的情况下,我的直觉是这可能是使用异常的合适位置。

答案 1 :(得分:4)

有关此主题的详细讨论,请参阅How slow are Java exceptions?

答案 2 :(得分:1)

TL;博士

分离关注,IMO你应该这样做:

continue = checkSomething() && checkSomethingElse();

或者代码中可能存在其他设计问题。

该功能的关注点 - 您想要定义它(这可能是一个主观问题)? 如果错误符合函数的关注点,则不要抛出异常。如果你对错误是否符合问题感到困惑,那么函数可能试图自己完成太多的关注(糟糕的设计)。

错误控制选项:

  1. 不报告错误。它要么直接由功能处理,要么无关紧要
  2. 返回值是
    1. null而不是对象
    2. 错误信息(甚至可能是与成功时返回的对象不同的数据类型)。
  3. 传入的参数将用于存储错误数据。
  4. 触发事件
  5. 如果发生错误,则调用传递给函数的闭包。
  6. 抛出异常。 (我认为通常只有在它不是任意定义的函数目的的一部分时才应该这样做)。
  7. 如果代码的目的是检查某个状态,那么知道状态为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;

如果您提前退出,则无需使用该标志。