封装异常处理并在每一层的顶层提供处理器:你可以专注于只处理业务逻辑相关的异常。处理器可以为特定层剩余的异常执行标准操作:记录日志、系统管理提示及转换等等。
通过“简单生活”方式来建模异常类层次:不要在发现新的错误类型时就创建新的异常类。首先问一下是否可以作为其他类型的变体来对待或者调用者确实需要捕获。记住异常至少在某方面是可以用他的属性来为不同的状况建立变化模型的对象。较少的异常类在开始时是足够的,但也仅在这种情况下可能需要用特定属性来处理。
提供有意义的信息给使用者:未处理的异常代表不可预知的事件和问题。告诉用户并且保存细节给技术支持人员。
虽然在不同的项目中需求、限制、异常层次及通知机制会有所不同,但许多元素还是一致的。因此为什么不完全地通过框架实现通用的策略呢?依据简单使用原则的框架是强制使用策略的最好方法。通过jar文件与javadoc之类的可执行工件与开发人员对话比白纸和幻灯片更容易表示架构准则。
然而,你不能要求开发团队直到异常处理策略及附加的框架支持准备完毕后才开始错误处理。错误处理必须在第一个源文件创建时确定。一个好的启动方法是定义基础的异常层次。
基础异常层次
我们首要的任务是定义一个可以跨项目的通用异常层次。这里的非强制异常基类是UnrecoverableException,由于历史原因,这个名字可能会有些误导。你可以在自己的层次中使用更好的名字
当你不想使用强制异常时WrappedException可以提供一种简单通用的传送机制:包裹原来的异常并重新抛出。WrappedException保存原始异常作为内部引用,这使得当类需要原始异常时也可以可以正常工作。当这不重要时,你可以使用SerializableException,他类似于WrappedException,此外还可以在客户端没有对类库作任何假设的情况下使用。
虽然我们偏好和推荐非强制异常,但你可以保留强制异常作为可选项。InstrumentedException是一个支持强制非强制异常的接口,他遵循一定属性实现模式。他允许异常处理者一致地检查来源页不需要考虑是来自强制或非强制的异常。
下面的类图显示了我们基础的异常层次。

这时候我们已经拥有了一个策略及相应的一组可以被抛出的异常。现在是时候建立安全网了。
防守的底线
“创建应用范围的用户会话”这篇文章描述了Rampart,一个使用了由企业信息系统层,基于无状态会话bean的业务层及基于网页和标准J2SE客户端的客户层的分层架构。异常可以从任意层次抛出,可以在线处理或者延迟到调用链的最终端。J2SE和J2EE应用服务器都可以通过捕获未处理的Errors和RuntimeExceptions来抵御侵入性的行为,通过输出栈信息、记入日志或者执行其他默认的操作。在任何情况下,用户都不应该看到输出信息,通常是没有意义的甚至影响程序稳定性的错误。因此我们必须构建自己的壁垒来提供更好的异常处理机制来维持这一防守的底线。看一下图2:

