`
duyouhua1214
  • 浏览: 236834 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

设计异常管理系统

    博客分类:
  • Java
阅读更多

——针对有效的错误处理设计异常管理系统
作者:Jean-Pierre NorguetJavaWorld.com,11/15/07

      在面向对象的应用程序中,由于代码重载、错误的问题处理方式,导致异常有越来越多的趋势。在这篇文章中,作者Jean-Pierre Norguet介绍了如何设计异常,来实现一个简单的、可读的、健壮的、灵活的、面向调试的及用户友好的错误处理系统。在本文中,作者提出了简单异常集合的设计,并且给出了Java实现的源代码。最后,作者介绍了如何将这样的设计集成到一个Java的企业应用程序中。

     
在一个面向对象的项目中,设计异常处理的最好途径从来也没有如我们期待的那样清晰。在旧的大的系统中,异常的发生有激增的趋势,最终达到几百行的代码。对于一些常见的编程场景,异常检查是必须的,但是也会带来可观的处理开销。虽然安静的异常捕获可以找到问题的源头,但是避免不了它的一些缺点(虽然这些缺点不是致命的);比如你必须熟悉这些代码。

      本文将介绍如何通过有限的异常集合来满足一个错误处理的需求。在建立起一个好的错误处理系统框架之后,将会指出异常处理设计中常见的错误,这些错误将会逐渐损害应用程序的性能;然后将会给出一个异常集合的例子,这个例子支持本文讨论的异常处理设计的基本功能:异常系统应该被设计成能够帮助外部系统(用户)处理未知情况(在运行时发生),而不是设计成能够帮助编程人员处理已知情况;还会介绍本文给出例子中的各个类的含义以及如何在一个特定的Java企业应用程序体系中使用它们;最后给出这个例子的Java实现。

错误处理需求

什么是一个好的错误处理系统?抛开审美角度的考虑,一个好的错误处理系统通常要符合下面的条件:
1
、任何异常都不会导致应用系统的崩溃。
2
、在发生异常时,允许应用程序进行相应的处理。
3
、显示给用户的错误信息要清晰的描述发生了什么错误以及应该采取什么样的处理。
4
、如果需要辅助信息,错误信息还要帮助用户与帮助部门交互,为帮助部门团队提供必要的信息,
    
使他们能够快速的容易的重现错误。

5
、日志信息能为开发团队人员在识别错误、在应用程序代码中定位错误产生的位置以及修正错误提供必要的信息。

6
、错误处理代码不会降低应用程序代码的可读性。必要的时候,错误处理仅仅是一个安全网,它对应用程序的核心功能具
   
有较低的访问权限。

     
一个错误处理系统的设计符合这些条件才能被认为是完整的。对于大多数Java开发人员来说接下来的问题就是:如何灵活的使用异常类来设计一个错误处理系统,而不是通过简单的重载它们来实现。

应该避免的常见用法

可以通过一个有限的异常类集合来满足上面提到的需求。当设计这样的一个异常类集合时,你应该避免一些常见的用法,例如:
1
、对每个问题都定义的异常类,这样会导致系统中异常类的激增。
2
、对每个包定义一个异常类集合,这没什么用处而且也会导致系统中异常类的激增。
3
、对每个异常都提供checkednon-checked两个版本,引入了检测异常开销。异常语义的后续副本也会混淆异常处理的设计。
4
、最后,抛出和捕获通用异常在很多方面也是错误倾向。

      
本文下面提到的异常类集合按照错误处理语义分类,避免了异常处理相关的常见问题。尤其是在应用程序的规模和复杂程度增长是,这种方式更值得推荐。

异常处理设计

1展示了异常类集合的设计,这个设计避免了异常类激增、检测异常开销和异常的安静捕获。

1.一个异常类集合的例子

    
在这个图中你会发现有些异常是checked,而有些是runtime。为了避免异常抛出声明的开销,checked异常基于下面两个目的被保留下来:

1.       告诉调用方法,在这个处理过程中发生了一个可预见的意外情况。在这种情况下,问题的语义已经被处理方法定义了,直接捕获会更好。

2.       告诉外部系统发生了一个未解决的问题,需要根据异常语义来处理这个问题。

理解异常语义

    在这里阐明本文对异常语义的定义。在作者看来,设计对象的类需要根据它们在现实世界中的等价物。一个水果或者一个人很容易设计成一个Java对象类。但是异常设计却不同:因为一个水果或者一个人在现实世界中非常直观,异常却不同。实际上,上面的两类异常中,只有第一类在现实世界中存在;而第二类异常模拟了系统执行过程中会发生什么错误,因此在系统之外就不存在了。直接捕获因此也只对第一类异常适合。

    
作者的设计建议就是异常应该根据它们的目的来设计。系统内部的、自我调整的异常就意味着是帮助系统来处理不可预见的情况。这些异常的目的也就不是模拟系统中的问题,而是给一个系统需要采取什么措施的指示。

一个异常类集合的例子

在图1中你可以看到四类异常对应四类处理,如下:

1.       BusinessException:一种异常情况发生。这种情况是可预见的,也可以被调用方法检测到并立即采取措施。

2.       ParameterException:输入的数据对处理过程不合法。用户被要求重新输入有效数据或者修改处理过程的条件。

3.       TechnicalException:技术问题,如无效的SQL语句。这种情况下,请求操作未完成。用户需要和帮助部门联系,调查问题的原因;或者尝试其它的服务。对使用系统的其它用户没有影响。

4.       CriticalTechnicalException:技术问题,如数据库崩溃。用户被建议稍后重试。在问题修复前,所有的用户都不能使用系统。

    这个异常类集合只是一个例子;很多异常类集合都可以参照它来定义。例如,TechnicalExceptionCriticalTechnicalException可以被设计成一个类,这个类声明一个severity布尔属性。重要的是关注采取什么处理措施而不是什么问题引起异常。

异常日志记录

    虽然异常语义关注采取的措施,但是出现的问题也很重要。例如,开发团队人员可以使用这些信息调试代码。在异常处理设计中,导致异常的信息能够在以用程序的错误日志中发现。在适当的位置使用一个好的日志记录框架,这个框架能够有效的从异常信息和堆栈跟踪中记录问题信息。

    
剩下的唯一问题就是怎么样设计异常类使之能够方便的返回信息。一个解决方案就是为异常类声明一个id属性来代表遇到的问题的种类。另外,问题自身可带有通用异常,也就是把通用异常内嵌到应用程序异常中。在捕获的时候,原始的信息和堆栈跟踪信息能够通过内嵌的异常得到。id属性和内嵌异常是包装问题的两种途径。

异常处理流程的设计

    一旦你已经设计好异常类本身了,下一步需要思考的就是它在应用程序中的处理流程。一个标准的JEE应用程序体系通常包括四个部分:展现、业务、集成、持久。异常经常在集成和持久部分被抛出。在业务部分,里层的捕获checked异常,而外层捕获runtime异常并根据它们的类型来采取相应的处理措施。也可以在业务部分抛出一些checked异常并且捕获它们。在这种模式下,集成和持久部分,包括业务部分的里层都将runtime异常转化成具体的处理措施。图2展示的就是一个典型的JEE应用程序异常处理流程。

2.标准JEE包体系中异常的处理流程

     
异常抛出路径是指从持久部分(假设)发生问题到问题被解决所经历的流程。如果持久层的调用方法能够解决这个问题,那么这个异常就直接被捕获并采取相应的处理措施,业务流程一切照常;如果问题不能被解决,异常将内嵌到一个runtime异常中经过业务部分的中间层传递到应用程序的上层中,在这里,典型的处理方法就是使用一些应用程序控制器来捕获这些runtime异常并采取相应的处理措施,展现层显示相应的错误信息给用户。直接捕获checked异常和推迟捕获runtime异常是异常处理设计中的两种主要方案,如图3所示。


3.直接捕获checked异常和推迟捕获runtime异常

扩展java.lang.Exception

    文中提到的异常处理设计方案在任何的面向对象语言中都可以很容易的实现,包括Java。一个相似的异常类树已经在标准Java库中提供了。在这个库中异常被设计为java.lang.Throwableckeched异常被设计为java.lang.Exceptionruntime异常被设计为java.lang.RuntimeException

    
java.lang.Exception下,有大量泛语义的业务异常。运行时应用程序异常,如ParamterExceptionTechnicalExceptionCriticalTechnicalException(见图1)各自都设计成相应的概要异常,如IllegalArgumentExceptionMissingResourceExceptionIllegalStateException

    
在应用程序中,重用Java标准异常是一个不错的主意,但是由Java标准类抛出的异常也会导致一些混乱。你可以通过扩展java.lang.Exception自定义异常类树来避免这样的混乱。通过自定义的异常类树,你还可以实现内嵌异常和问题ID。列表1给出了文中例子的Java代码实现。注意,它包括内嵌异常和问题ID

列表1.通过Java代码实现内嵌异常和问题ID
public class NestedException extends RuntimeException {
  protected Exception nestedException;
  protected int issueId;
  public NestedException(String msg, Exception e, int id) {
    super(msg);
    this.nestedException = e;
    this.issueId = id;
  }

public Exception getNestedException() {
  return this.nestedException;
}
public int getIssue() {
  return this.issueId;
}
}

public interface Issue {
  public final static int UNDEFINED = 0;
  public final static int EXTERNAL_SERVICE_1_DOWN = 1;
  public final static int EXTERNAL_SERVICE_2_DOWN = 2;
  public final static int SQL_STATEMENT_ERROR = 3;
// ...
}

总结

    设计一个满足好的错误处理系统需求的异常类树非常简单。简单的秘诀就是将设计的主要精力集中在系统应该采取什么样的处理措施,而不是关注会出现的什么样的问题。在本文的设计当中,问题的信息封装在异常类里面。通过在处理措施和问题之间分配异常语义,让你将异常类树限制在一个有限的异常类集合中(可能就六七个左右)。这种设计不仅限制了异常类激增,保证代码的可读性,使你在以后的开发中以最佳的清晰度来关注应用程序的业务逻辑的编码。

作者简介

   Jean-Pierre Norguet拥有布鲁塞尔大学的计算机科学和网络工程博士学位。在IBM经过了三年全职的电子商务应用程序关键任务的Java开发后,作为团队领导者和教练,他擅长的技术领域包括了整个应用程序开发周期。目前专注于Java技术、实体集成和迷你Web应用的研究。除了一些在线Java文章外,Norguet博士还与PrenticeIBM出版社一起出版了有关JEE的著作,同时还在ACMIEEESpringer-Verlag的国际研讨会发表了一些文章。他的业务兴趣还包括艺术绘画、兼职法语教师和临时健康顾问。

 

文章来源:网上

 

分享到:
评论

相关推荐

    酒店管理系统毕业设计源码

    【酒店管理系统毕业设计源码】是一个典型的IT项目实践案例,主要涵盖了软件开发中的多个关键知识点。这个系统的设计和实现能够帮助学生或者初学者提升编程技能,理解实际项目开发流程,并积累实践经验。 首先,从...

    数据库课程设计 图书管理系统

    图书管理系统是一个典型的数据库应用案例,它涉及到多个方面,包括数据模型设计、数据库表结构规划、查询优化以及用户界面设计等。在这个项目中,学生将有机会实践如何构建一个能够有效地管理和检索图书信息的系统。...

    数据库课程设计 医院管理系统

    综上所述,"数据库课程设计-医院管理系统"涵盖了数据库设计理论、SQL编程、Java应用开发、业务流程理解、用户界面设计、异常处理、安全性和测试等多个IT领域的知识点,是学习和实践IT技能的综合性项目。通过这个项目...

    数据库课程设计——教学管理系统(C#含源码)

    数据库课程设计是IT教育中的重要组成部分,而教学管理系统作为一个典型的案例,经常被用来教授数据库设计、编程以及系统集成等核心概念。在这个项目中,我们关注的是一个基于C#语言实现的教学管理系统,它提供了完整...

    教务管理系统概要设计和详细设计说明书

    本说明书主要涵盖了教务管理系统的概要设计和详细设计两个关键阶段,旨在为软件工程的学习者提供一套完整的系统开发流程。 概要设计阶段是软件开发的早期阶段,其主要目标是确定系统的整体架构和主要功能模块。在...

    C#课程设计-超市管理系统

    【C#课程设计-超市管理系统】是一个典型的基于C#编程语言的项目,旨在提供一个全面的解决方案来管理超市的日常运营。这个系统包含了程序代码、数据库设计以及相关的设计报告,展示了从需求分析到系统实现的完整流程...

    java仓库管理系统(期末课程设计)

    【Java仓库管理系统】是一个基于Java编程语言开发的期末课程设计项目,主要目的是让学生掌握实际的软件开发流程,尤其是涉及到数据库管理的部分。系统的核心是利用Java技术实现仓库的库存管理、出入库操作、商品信息...

    学生成绩管理系统 Mysql,学生成绩管理系统mysql课程设计,Java

    学生成绩管理系统是一款基于Mysql数据库,采用Java编程语言实现的课程设计项目。这个系统的主要目的是为了方便教育机构或教师对学生的成绩进行有效管理和分析,从而优化教学过程,提升教学质量。下面将详细介绍这个...

    java课程设计汽车修理管理系统

    Java课程设计:汽车修理管理系统 本项目是一款基于Java技术实现的汽车修理管理系统的课程设计,旨在让学生掌握Java编程语言在实际应用中的技能,特别是对于客户端/服务器(C/S)架构的理解与运用。在这个系统中,...

    c++课程设计餐厅管理系统

    首先,C++作为一门面向对象的编程语言,其在餐厅管理系统中的应用涉及到类的设计和对象的创建。类是C++中的核心概念,可以抽象出餐厅管理系统中的各种实体,如菜品、订单、客户和员工等。每个类应包含相关的属性(如...

    【C++课程设计】图书管理系统

    【C++课程设计】图书管理系统的项目旨在提供一个在控制台上运行的图书信息管理平台,让学生熟悉C++编程语言,并掌握面向对象编程的基本概念。这个系统可以实现对图书的添加、删除、查询以及借阅等操作,对于学习C++...

    库存管理系统 数据库课程设计

    【库存管理系统 数据库课程设计】是一项大学数据库课程的实践项目,旨在让学生掌握数据库设计与管理以及Java编程技术的综合运用。在这个项目中,学生利用Java编程语言和SQL数据库语言,构建了一个用户友好的库存管理...

    c++课程设计--学生成绩管理系统

    在"学生成绩管理系统"的课程设计中,学生将运用C++的基本语法、类与对象、文件操作、异常处理等核心概念,构建一个能够存储、管理并分析学生分数的应用程序。 1. **类与对象**: C++中的类是数据和操作的集合,是...

    c#课程设计图书管理系统

    总结,完成"C#课程设计图书管理系统"项目,需要扎实的C#编程基础,理解面向对象编程,掌握数据库操作,具备一定的UI设计能力,熟悉文件操作,以及具备基本的异常处理和测试技巧。这个过程不仅能提升技术能力,也能...

    java学生管理系统界面设计

    总结来说,"java学生管理系统界面设计"项目涵盖了Java GUI编程、数据库设计与操作、软件架构设计、异常处理以及国际化等多个核心知识点,是一个全面的Java编程实践案例。通过这个项目,开发者可以提升自己的全栈开发...

    异常处理.doc

    本文作者Jean-Pierre Norguet探讨了如何设计异常管理系统,以实现简单、可读、健壮、灵活、面向调试和用户友好的错误处理。 首先,异常处理的目的是防止程序因未预期的错误而崩溃,并在出现异常时提供适当的反馈和...

    JAVA毕业设计<<毕业设计管理系统>>

    【JAVA毕业设计管理系统】是一个基于JAVA技术的项目,它整合了STRUTS1.2框架和MYSQL数据库,旨在实现一个全面的毕业设计管理解决方案。这个系统不仅为学生提供了一个提交、跟踪毕业设计进度的平台,同时也方便教师...

    学生管理系统详细设计说明书

    《学生管理系统详细设计说明书》是一份详尽的文档,它涵盖了构建一个高效、全面的学生管理系统的各个关键方面。这份说明书的目的是为开发团队提供清晰的指导,确保系统的设计符合业务需求,同时也便于后期的维护和...

    数据库课程设计学生宿舍管理系统

    在数据库课程设计中,学生宿舍管理系统是一个典型的案例,它涵盖了多个关键知识点,旨在帮助学习者理解和应用数据库原理、软件工程方法以及用户界面设计。以下是这个系统所涉及的主要技术点: 1. **数据库设计**:...

Global site tag (gtag.js) - Google Analytics