关于自定义异常的层次

时间:2021-07-06 15:22:48

     纵观众多的开源框架,甚至是jdk自身,异常几乎总是按一定的类层次结构组织起来。那种认为一个系统只需要提供一个异常基类,其余所有异常都是只需要继承这一个基类的观点是武断和片面的。我们至少可以从两个方面来认识异常层次的重要性:
 
      一、有时候我们关心某一种具体的异常,需要对其做特别地处理,而有的时候,我们只需要对“一组相近”的异常做出同样的处理,在这种情况下,设计良好的异常体系就体现出了它的价值。此时我们只需要catch它们共同的直接父类而不必catch每一个子类并复制同样的异常处理代码。
 
      二、有人认为一个异常被设计出来而不被throw和catch是没有任何意义的。但是做为良好设计的产物,我们确实会在一些优秀的产品和框架中发现一些异常类,它们的主要作用就是用来被继承。或者更加确切地说是对异常进行“划分”。这种异常多是抽象类。就以经典的spring数据访问异常体系为例,作为处于异常体系中间层的org.springframework.dao.NonTransientDataAccessException,既非最高基类异常,同时又有众多的直接子类。从spring的源码中我们几乎找不到throw(org.springframework.dao.NonTransientDataAccessException是抽象类,因此不会有直接throw该异常的地方)和catch这个异常的代码。它的存在完全是与和它比肩的org.springframework.dao.TransientDataAccessException一起对异常做“范围划分“,在设计层面上体现合理的组织关系。像这种异常在众多产品和框架中大量存在。
 
      很多系统都不会出现层次过深的异常体系,多数情况下,可能是一些继承了同一基类的简单异常。但这并不表示我们没有设计异常体系的必要。在我看来,一个用户登陆异常和一个payment异常是毫无瓜葛的。如果它们的直接父类是同一个,似乎很难说得过去。当然,话又说回来,不是可以,只是不够好罢了。