抛出异常来控制流代码的气味? [英] Throwing exceptions to control flow - code smell?

查看:142
本文介绍了抛出异常来控制流代码的气味?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个代码(特别是Java):

Consider this code (Java, specifically):

public int doSomething()
{
    doA();

    try {
        doB();
    } catch (MyException e) {
        return ERROR;
    }

    doC();
    return SUCCESS;
}

其中 doB()被定义为:

private void doB() throws MyException

基本上, MyException 只有在 doB()满足一些条件(这不是灾难性的,但是需要以某种方式提高此条件),以便 doSomething()将知道退出并出现错误。

Basically, MyException exists only in case doB() meets some condition (which is not catastrophic, but does need to somehow raise this condition) so that doSomething() will know to exit with an error.

您是否发现使用异常,在这种情况下控制流程,可以接受吗?还是这个代码气味?如果是这样,你会如何重构?

Do you find the use of an exception, in this case to control flow, acceptable? Or is this a code smell? If so, how would you refactor this?

推荐答案

它完全取决于什么是错误条件,什么方法的工作。如果返回 ERROR 是一种处理调用函数的错误的有效方式,为什么会这样坏?

It entirely depends on what that error condition is, and what the method's job is. If returning ERROR is a valid way of handling that error for the calling function, why would it be bad?

然而,通常它是一种气味。考虑一下:

Often, however, it is a smell. Consider this:

bool isDouble(string someString) {
    try {
        double d = Convert.ParseInt32(someString);
    } catch(FormatException e) {
        return false;
    }
    return true;
}

这是一个非常大的代码气味,因为你不期望一个双值。你只想知道一个字符串是否包含一个double。

That is a very big code smell, because you don't expect a double value. You just want to know whether a string contains a double.

有时,您使用的框架没有其他方法来做你想要的。对于上述,有一个更好的方法:

Sometimes, the framework you use doesn't have other ways of doing what you want. For the above, there is a better way:

bool isDouble(string someString) {
    bool success;
    Convert.TryParseInt32(someString, ref success);
    return success;
}

这种异常有一个特殊的名字,由一些兄弟创造的博客我的最近阅读可悲的是,我忘了它的名字。如果你知道的话请评论。最后但并非最不重要的是,以上是伪代码。我不是ac#开发人员,所以上面没有编译,我敢肯定,但TryParseInt32 / ParseInt32演示了我很好,所以我要用C#。

That kind of exceptions have a special name, coined by some dude whose blog i read recently. But sadly, i forgot its name. Please comment if you know it. Last but not least, the above is pseudo code. I'm not a c# developer so the above doesn't compile, I'm sure, but TryParseInt32 / ParseInt32 demonstrates that well i think so i'm going with C#.

现在,你的代码。我们来检查两个功能。有一个气味,另一个没有:

Now, to your code. Let's inspect two functions. One smells, and the other doesn't:

public int setupSystem() {
    doA();

    try { doB(); }
    catch (MyException e)
    { return ERROR; } 

    doC();
    return SUCCESS;
}

这是一个代码气味,因为当你想要要设置系统,您不希望它失败。无法设置系统意味着您无法继续处理该错误。

That's a code smell, because when you want to setup a system, you don't want it to fail. Failing to setup a system means you can't continue without handling that error.

public int pingWorkstation() {
    doA();

    try { doB(); }
    catch (MyException e)
    { return ERROR; } 

    doC();
    return SUCCESS;
}

这样可以,因为该方法的目的是测试工作站仍然可以到达如果不是,那么这是该方法的结果的一部分,而不是需要替代返回路径的特殊情况。

That is ok, because the purpose of that method is to test whether the workstation is still reachable. If it's not, then that is part of the result of that method, and not an exceptional case that needs an alternative return path.

这篇关于抛出异常来控制流代码的气味?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆