如何在架构层面规划例外?

时间:2008-09-17 20:35:40

标签: java exception architecture

是否有任何好的资源可用于规划从架构角度使用异常的方式? (或者直接在这里提供你的建议。)在我工作的项目中,我发现一些常见的异常被反复使用并且往往会失去意义。 来自:http://jamesjava.blogspot.com/2007/10/exception-plan.html

4 个答案:

答案 0 :(得分:2)

我通常发现,对经过检查的例外情况进行过度研究是过度的。应该为程序无法合理恢复的意外错误条件保留例外。对于这些,我倾向于同意你所观察到的,特殊的错误类型往往会失去意义。

作为一般规则,在满足以下所有条件时抛出异常:

  • 此情况无法恢复。
  • 无法合理地预期来电者会从这种情况中恢复过来。
  • 有人会想调试这种情况,因此他们可能希望看到堆栈跟踪。

你会发现如果所有这些都是真的,那么异常的类型并不重要,你也可以抛出java.lang.Error。如果它们中的任何一个都是假的,那么异常可能是过度的(你真的需要类型,消息和堆栈跟踪吗?)

相反,请考虑增加方法的返回类型以指示预期的失败类型。例如,对于在某些情况下不返回任何值可能有意义的方法,请使用Option<A>类型。对于可能需要返回类型取决于失败或成功的值的方法,请使用Either<A,B>类型。在您之前可能有过专门的异常子类型的情况下,您只需使用Either&lt; Fail,A&gt; “失败”只是对预期失败类型的枚举。

答案 1 :(得分:2)

我同意Apocalisp的评论。对于发生数据或处理错误但可以通过用户或系统干预恢复的情况,应保留异常实例。 RuntimeException的实例应保留在应用程序范围内的任何干预都无法解决问题的情况下。因此,这两种类型称为已检查和未检查的异常。

未经检查的异常的示例是物理资源(例如数据库或消息总线)不可用。在这种情况下,RuntimeException很好,因为您没有计划资源不可用,因此您的业务逻辑不必经常检查DatabaseUnavailableException或类似的东西。您可以以不同的方式处理RuntimeExceptions(可能是AOP发送电子邮件)以报告中断,并让员工或支持人员解决物理问题。

Checked异常的示例包括糟糕的数据输入,或不完整的数据访问或实际上失败的业务逻辑,但可以检查和恢复。例如,您搜索的用户不可用。这是您的业务逻辑中的一个单独条件,可以检查和处理(例如,应用程序的View部分,然后将Exception的消息作为错误消息报告给用户)。

许多框架都使用这个模型,它似乎比我见过的更好。

话虽如此,许多人确实用返回的空值,-1,空字符串或Number.MIN_VALUE替换已检查的异常。虽然这没关系,但如果您不是经常期望从数据源或方法中获取这些值,那么它应该表示为异常。

答案 2 :(得分:0)

"Effective Java," 2nd. ed. Bloch,在第9章中有一些很好的建议。

"Hardcore Java," Simmons,在第5章中有一些很好的建议。

我还会无耻地提到我已经编写a small tool来管理Java异常源代码。异常代码通常非常冗余,您通常关心的只是类型。我的工具接受一个命名异常类型的配置文件,然后为这些异常生成代码。

答案 3 :(得分:0)

我尝试确保使用try / finally的地方数量大大超过了使用try / catch的地方数量。 catch通常会保留用于捕获顶层的异常 - 可以合理地处理它们,或者处理来自平台API的异常。

在这种情况下,只要您提供有意义的异常消息,并在必要时链异常,无法通过其类识别异常并不是一个很大的损失。我经常抛出RuntimeException而不是尝试为每个可能的错误案例开发一个异常类 - 但是你对此的看法将取决于你在被检查与未经检查的异常辩论中的位置。