锁定老帖子 主题:异常捕获的切面--java需要优雅吗?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-08-08
今天看到前人的两行注释让我思考—— ……也许我所述不是问题for YOU,但是我迷茫 public synchronized void putInCache(String cacheName, String key, Object value){ CacheExt cache= getCache(cacheName); // if (cache == null) { // throw new NeedsRefreshException("Cache is not exist"); // } cache.putInCache(key, value); } 为什么要注释掉呢?可能是作者认为调用它的代码过滤了cache为空的可能,例如: public synchronized boolean hasCache(String cacheName) { return cacheMap.getKeys().contains(cacheName); } …… if(hasCache(cacheName)) { putInCache(……);} …… 但下面: public synchronized Object getFromCache(String cacheName, String key){ CacheExt cache = getCache(cacheName); if(cache == null) return null; try { return cache.getFromCache(key); } catch (NeedsRefreshException e) { cache.cancelUpdate(key); return null; } } 作者又在方法内部过滤这种异常,是作者的逻辑有问题吗? 当面对外部对本方法调用有多种可能性,而每种可能性的处理又个不相同时,就出现这样的问题: 本方法不能确定外部调用是否已经过滤了异常,而自己又很迫切的需要保证这一点时,你就得在自己内部过滤掉可能的异常。但是对于许多人来说:注意防止异常的发生是基本原则(至少老师是这么教我的——),所以对于一个充分解耦的程序来说多级的调用中,或者是分组开发里,出现这样的调用A-调用->B-调用->C-调用->D-调用->E-调用->F-调用->G的调用栈,G是最终的方法即本方法,内部有过滤,同样的A-调用->B有过滤,其他一样,既 if (cache == null) { throw new NeedsRefreshException("Cache is not exist"); } 出现多次,判断N次(影响效率!?)。这样我看起来很不爽,这么麻烦!一点都不简约,不朴素。 当然,也可以不处理这样就简约了,朴素了- 待续……去看奥运会开幕式—— 接续: 也就是说在类的外部和内部都不处理这种异常(有这样写代码的吗?),假设程序中不会出现异常;或者捕获这种异常的代价远远大于了重启的代价—— 当然,这里依然还有一种方法,也就是整个系统的通用异常处理框架或机制。如此的话,在函数方法的内部和外部(不包含最外部)不用理睬过滤的事情了…… 总结:当我们不确定异常发生的时机、异常处理的种类(也许有些异常出现后,可以使用默认参数代替,有些则报错崩溃)、异常处理代价时,就出现了异常处理的切面问题,也就是说在哪里会出现异常、哪里需要处理异常、如果处理异常的问题! 我认为有4种模式:
如果是这样的话,我想Java代码在我们面前突然就变得优雅起来。 但在日益复杂的系统里,这可能实现吗? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-08-11
可能getCache()方法被优化过了
不会返回null也不一定。 |
|
返回顶楼 | |
发表时间:2008-08-12
请看oscache的参考文档
|
|
返回顶楼 | |
发表时间:2008-08-12
leobluewing 写道 可能getCache()方法被优化过了
不会返回null也不一定。 sorphi 写道 请看oscache的参考文档
其实呢,我并不是说这个代码本身有什么含义,或者讨论它的健壮性。这段代码是个因子…… 所以在我的题目里没有出现cache等具体字眼。 ————见接前续———— |
|
返回顶楼 | |
发表时间:2008-09-28
sorphi 写道 请看oscache的参考文档 |
|
返回顶楼 | |
发表时间:2008-12-02
这不是优雅的问题,是你对程序结构理解的问题,一个没有好的异常体系的系统不是一个优秀的系统只是我这么觉得. 异常反复抓取是异常框架和程序员的问题.
请注意你上面的代码的方法定义,方法并不会抛异常所以他多判断一次多抛出一次,这个就是开发人员自身的问题了.(对于可测异常) |
|
返回顶楼 | |
发表时间:2008-12-08
请注意你上面的代码的方法定义
fjlyxx 写道 这不是优雅的问题,是你对程序结构理解的问题,一个没有好的异常体系的系统不是一个优秀的系统只是我这么觉得. 异常反复抓取是异常框架和程序员的问题.请注意你上面的代码的方法定义,方法并不会抛异常所以他多判断一次多抛出一次,这个就是开发人员自身的问题了.(对于可测异常) 我也觉得和系统的框架有关系,但是有些人这么写,有些人那么写,我难以确定那种更好些。 |
|
返回顶楼 | |
发表时间:2008-12-08
我认为异常不适于在一个统一的层面统一处理,由于系统是分层结构的,每一层都有各自的异常,异常属于这个层次的实现细节之一,一个层次不应该去处理其他层次的异常,比如你在写用户管理的Controller,调用UserServices,捕捉到NoUser异常,跳转到没有用户的错误页面,捕捉到ErrPassword跳转道密码错误页面,然而你发现还要处理FileNotFoundException,一下就蒙了,这个异常该怎么恢复?这说明在写UserServices没有把FileNotFoundException隐藏好...
|
|
返回顶楼 | |
发表时间:2008-12-08
我也支持bloodrate兄的观点...
DAO/Service/Controller都应该有各自不同的异常抛出.. 能处理则处理,不能处理则抛出,这里抛出不一定直接throw 当前捕获的异常,可以抛出自定义的异常...当然顶层需要一个统一的处理,处理那些没有被处理掉的异常 |
|
返回顶楼 | |
发表时间:2008-12-08
huangking 写道 我也支持bloodrate兄的观点...
DAO/Service/Controller都应该有各自不同的异常抛出.. 能处理则处理,不能处理则抛出,这里抛出不一定直接throw 当前捕获的异常,可以抛出自定义的异常...当然顶层需要一个统一的处理,处理那些没有被处理掉的异常 不是说统一处理,而是你要让你的调用者知道你出异常了。你可以发出一个通告给你的调用者你没有按照预定的规则进行处理。 特别是在多线程中如果你不通告回掉业务的线程业务处理出问题了那么这条线程就可能永远挂起了。 是通告不是一定要统一处理。 |
|
返回顶楼 | |