异常流量控制

时间:2017-12-08 09:34:12

标签: java design-patterns design-principles

我使用异常来控制流量,但我有一种奇怪的感觉,我做错了。编写类似于下面显示的代码的东西是一个好习惯吗?

public static void main(String[] args)
{
    try
    {
        methodA();
    }
    catch (Exception ex)
    {
        handleException(ex);
    }
}

public static methodA()
{
    methodB();
}

public static methodB()
{
    if(someConditionIsNotMet)
    {
        throw new RuntimeException("Some Condition Is Not Met");
    }
}

3 个答案:

答案 0 :(得分:1)

  

我使用异常来控制流量

抛出特定和功能异常以指示工作流程中的功能问题本身并不坏。
这不是单一的方式,但它是一种有效的方式 另一种方法依赖于返回boolean并测试返回值的方法 就个人而言,我不使用这种方式,因为我发现它相当冗长,容易出错(我们不要忘记测试返回的布尔值)而且表达力较差(它只有两个值:true和{{1 }})而不是异常(它可能有所需数量)。

假设方法B必须检查某些内容,并且如果检查失败,则应停止处理并向客户端通知该问题,为此目的使用例外是完全有效的。
现在,将异常作为特定异常而不是false更有意义 否则客户如何解释异常含义?
异常可能是工作流异常,但也可能是因为Exception等其他原因而在运行时抛出的异常。 您希望以特定方式处理工作流异常,而不会将特定处理应用于其他抛出的异常。

例如,你可以写一些东西:

NullPointerException

然后从客户端,您有两种方式 单独捕获每个异常或以通用方式捕获它们(只有当它们构成相同层次结构时才有可能)。

单独捕获每个例外:

public static methodA()
{
    methodB();
}

public static methodB(){
    if (!expectedDataFound()){
      throw new DataNotFoundException("data xxx was not found");
    }
    if (!hasRights()){
      throw new PermissionException("user xxx has not the rights for yyy");
    }
}

全局捕获异常:

public static void main(String[] args)
{
    try
    {
        methodA();
    }
    catch (DataNotFoundException ex)
    {
        handleDataNotFoundException(ex);
    }
    catch (PermissionException ex)
    {
        handlePermissionException(ex);
    }
}

答案 1 :(得分:1)

我认为你说你“使用例外来控制流量”对你自己太苛刻了。它是一个使用控制流异常的反模式,但在你的例子中却没有。

假设您有一个方法可以设置用户的年龄,当然如果调用者提供了负数,您就不应该完成操作。因此,确保这一点的一种非常合理的方法是:

public void setAge(int age) {
    if(age <0) {
        throw new InvalidArgumentException("Age has to be zero or positive number");
    }
}

如果您不想使用异常,也可以使用Optionals等语言的功能或创建处理成功和错误的响应结构。例如,假设您有一个检索员工的方法

public EmployeesOverview getEmployees() { ... }

您的回复课程可能如下所示:

public class EmployeesOverview {
    private Ok ok;
    private Error error;

    class Ok {
        private Set<Employee> employees;
    }

    class Error {
        private String errorMessage;
    }
}

因此,如果没有抛出异常,您的方法将为客户提供结果,或者如果出现问题,将通知客户。

答案 2 :(得分:0)

我会将流控制和异常处理分开。流量控制用于确保语句以正确的顺序和正确的条件执行。这必须在设计时确定。异常处理旨在处理运行时无法预料的情况。例外情况几乎总是由外部因素造成的:超时,无磁盘空间,数据错误......

只是我的两分钱。