java异常设计总结

 

异常争论

 

异常有两个模型:中止模型和继续模型

中止模型认为异常不应该再回来,他做的是善后工作。而继续模型保持异常时环境,希望再一次能运行成功。

Java采用的是前者(一般语言都是前者),而OS一般采用后者。

Java异常有三类:错误,运行时异常,检查型异常。

 

官方的观点是

39 条:最好为异常条件使用异常。也就是说,最好不为控制流使用异常。

40 条:为可恢复的条件使用检查型异常,为编程错误使用运行时异常。

41 条:避免不必要的使用检查型异常。

43 条:抛出与抽象相适应的异常。(使处理异常更直观)

在异常的使用上,专家的观点是很不一样的

C#作者Anders根本就忽略检查型异常。

Bruce Eckel,声称在使用 Java 语言多年后,他已经得出这样的结论,认为检查型异常是一个错误 —— 一个应该被声明为失败的试验。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

缺点1,代码中包含了过多的catch,使得代码不清晰

缺点2,有时候捕捉的异常没有什么实际意义

缺点3,不够清晰的错误指示。

缺点4,过深的异常层次。

缺点4,性能。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Eckel 提倡将所有的异常都作为非检查型的,并且提供将检查型异常转变为非检查型异常的一个方法,同时保留当异常从栈向上扩散时捕获特定类型的异常的能力

 

Rod Johnson 他采取一个不太激进的方法。他列举了异常的多个类别,并且为每个类别确定一个策略。一些异常本质上是次要的返回代码(它通常指示违反业务规则),而一些异常则是发生某种可怕错误(例如数据库连接失败)的变种。Johnson 提倡对于第一种类别的异常(可选的返回代码)使用检查型异常,而对于后者使用运行时异常。在发生某种可怕错误的类别中,其动机是简单地认识到没有调用者能够有效地处理该异常,因此它也可能以各种方式沿着栈向上扩散而对于中间代码的影响保持最小(并且最小化异常淹没的可能性)。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

解决1:谨慎的抛出检查型异常。或者你认为,你可以处理它。否则,包装为运行时异常。

解决2:如果遵守12不是问题

解决3:异常不跨层,否则必须捕捉或者包装。

         比如持久层丢出的SalException,你或者丢弃/处理/包装(为运行时异常),或者重新包装为业务层异常。保持JEE层的独立和异常的清晰性。

         包装底层异常,保持异常链。

解决4:如果符合14也不是问题。再次强调,能捕捉就捕捉。

解决5:减少异常使用,减少层次。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

 

je里面,robin认为异常是流程控制的一部分——当然,考虑到性能问题,这个流程不应该是大概率流程——也就是异常流程

例如用户登录

Try{

用户登录(用户名,密码);

登录成功;

}catch(没有这个用户异常 e{

         错误提示界面;

}

Potian则认为,没有用户是正常业务逻辑的一部分

If(!用户业务层.没有这个用户(用户名))错误提示界面;

If(用户业务层.检验密码(用户名,密码))登录成功;

else 登录失败;

Potian认为不应该在一个业务中包含了过多的责任。

 

Ps:在servlet中,我喜欢仅仅简单的在action中调用最好一个业务层方法就可以完成此action的任务。这意味着我的servlet非常瘦,可以比较容易的被替换。如果采用了potian的办法,则意味着我要把业务层中的代码前移到servlet中来,这模糊了业务层的责任。解决的办法是回到老路子上来。

Ps:我还认为,没有异常的业务方法表达能力太弱,异常给了他们更丰富的表达能力。这使得业务层可以更丰富的表达业务意义。避免将业务责任分散掉。

 

我认为在业务层中,恰恰要包含足够的责任。不多也不要少(流程分支-2最好)。在别的层次中,要细致一点。

posted on 2007-05-11 15:22 wanglin 阅读(3649) 评论(1)  编辑  收藏

评论

# re: java异常设计总结 2007-06-30 22:16 wanglin

关于异常的再次总结

1,符合j2ee分层
即异常不跨层,跨层必须封装
2,性能
如果在同一个方法内捕捉和处理掉异常,性能影响很小。但是如果要到堆栈里面,性能就影响比较大。
所以能处理就处理,不能处理就封装再throw。如果不适合再次封装(封装层次太多也不好)那么就直接throw吧,这种情况要慎重
关于封装的问题,看异常的分类
从语法上分error和exception,前者不提,后者又分runtimeexceptioin和exception。后者是可以处理的异常.
常常提uncheckexception和checkexception,前者是我们无法处理的,建议转化成runtimeexception。后者我们处理。
我们处理异常的时候,要注意异常信息的丢失,使用异常链。
3,关于异常的new throw.....以及业务逻辑
我是赞成用异常控制逻辑的。
oo编程,仅仅靠返回值表达业务逻辑能力太有限了,如果返回字典符号也不自然。异常框架设计的好,性能的问题是不大的。
  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2007年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

常用链接

留言簿(1)

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜