抛出异常有些困惑

时间:2014-08-01 14:41:17

标签: java

我有一个名为Handle的类,它基本上管理服务器的嵌入式(图形)数据库。在企业bean框架中,有一个bean管理这个对象,并公开可以被各种用户/ bean等调用的Web服务。

此类所做的一件事是验证针对架构的提交。有很多可能的检查。例如,如果要在数据库中创建图形,它将根据模式验证您的提交,并检查它是否内部一致,并在尝试访问数据库之前执行所有这些检查。

现在,这个验证方法表面上是一个布尔函数,但实际上它永远不会返回false,它会返回true,或抛出一个异常,详细说明验证失败的原因。

现在这似乎是一个经典案例,你通常不会抛出异常,因为完全可以预测有些人会无法通过验证,事实上,这几乎就是进行验证。

另一方面,如果您不抛出异常,则无法通知调用该函数的bean,并从那里通知最终用户,这正是他的提交未通过验证的原因。他只是得到了错误的#34;背部。当bean处理异常并依赖于抛出异常时,会向用户返回一条短消息,说明它是如何失败的。

这是否有效使用例外?我应该在这里使用其他一些模式吗?

一切正常,但它似乎违反了例外的一般原则,即它们应该是罕见的并且指的是不可预测的行为。

3 个答案:

答案 0 :(得分:1)

我们为每个类都有两种验证方法:

如果实例无效但是没有返回值,则会抛出异常:

void validate () throws SomeException;

另一个返回一个布尔值,指示实例是否有效,并且不会抛出任何异常。

boolean isValid ();

我建议你使用其中一种方案。任何一个比返回boolean 的方法更有意义,而在实例无效时抛出异常。

答案 1 :(得分:1)

我认为这取决于你想如何对待失败" :

  1. 如果您只想知道某些内容是否有效,那么最好使用一个只返回true或false的方法(如Pattern.matches或Object.equals)

  2. 如果最终用户知道'如何使用方法(或系统),您最好使用枚举,表示结果的对象,甚至是您返回的对象中的特殊属性。例如:

    • 产品getProduct(Integer id){}如果产品存在则返回null
    • 包含代表请求答案的代码的HTTP标头(200,404,...)
  3. 如果您的最终用户不知道'系统,你想强迫他处理问题因为它可能导致不安全的状态,你最好使用你当前使用的方法。它不是优雅的,但它是安全的。

    Boolean myMethod () throws ExceptionFailure1, ExceptionFailure2, ... {...}
    

答案 2 :(得分:1)

我不会在这种情况下使用例外,因为失败的验证是例外结果。

由于您需要传输的信息多于简单的ok / not,我会使用一个返回Enumeration ValidationStatus的验证方法,其中每个枚举值对应一个例外当前抛出的对象ValidationResult由枚举和其他信息组成,以解决问题:

public enum ValidationStatus {
  SUCCESS, ERROR1, ERROR2
}

public class ValidationResult {

    private ValidationStatus status;
    private String errorMessage;

    public ValidationResult(ValidationStatus status, String errorMessage) {
        this.status = status;
        this.errorMessage = errorMessage;
    }

    public boolean isValid() {
        return status == ValidationStatus.SUCCESS;
    }

    public ValidationStatus getStatus() {
        return status;
    }

    public String getErrorMessage() {
        return errorMessage;
    }
}

我认为创建这些ValidationResults可以发生在当前抛出异常的相同位置。