When is it OK to use exception handling for business logic?
我认为,作为Java中的一个通用规则(也许任何语言都有异常处理),人们应该尽量避免使用异常处理来真正处理业务逻辑。一般来说,如果预期会发生某种情况,那么应该检查并更直接地处理它,而不是依赖异常处理来为您进行检查。例如,以下不被视为良好做法:
1 2 3 4 5 | try{ _map.put(myKey, myValue); } catch(NullPointerException e){ _map = new HashMap<String, String>(); } |
相反,惰性初始化应该更像这样完成:
1 2 3 4 |
当然,逻辑可能远比简单地处理延迟初始化复杂得多。因此,考虑到这种类型的事情通常是不受欢迎的……如果有的话,当某个业务逻辑发生时,依赖发生的异常是一个好主意吗?是否准确地说,任何一个被迫使用这种方法的实例实际上都突出了正在使用的API的弱点?
无论何时,只要可以预料到例外,但不能避免。
例如,如果您依赖某种类型的外部API来解析数据,并且该API提供了解析方法,但是没有任何内容来说明给定的输入是否可以被解析(或者解析是否成功取决于您无法控制的因素,但是API没有提供适当的函数调用),并且解析方法抛出了异常当无法分析输入时打开。
有了一个设计得当的API,这应该归结为一个在"几乎从不"到"从不"范围内的数量。
我完全没有理由在代码中使用异常处理作为正常的流控制手段。它很昂贵,很难阅读(看看你自己的第一个例子,我知道它可能写得很快,但是当
编辑:只要清楚,上面的答案是用Java编写的。其他语言(显然也有)在例外的实现开销上可能有所不同,但其他观点仍然适用。
抛出异常是C++中相对昂贵的操作,也是Java中非常昂贵的操作。仅仅从效率的角度来看,避免一个明确的检查并接受一个例外是没有意义的。我想,在一些罕见的情况下,您可能能够证明这一点,在这种情况下,检查是否抛出异常非常复杂或几乎不可能,但否则,我会说答案是"几乎从未"。
这确实是一个讨论问题,答案取决于系统的设计。
我的直觉永远是一张毯子,从来没有,但我见过一些系统使用异常实现业务错误。我个人觉得这很恶心,但是我真的理解一旦你知道一个业务流程失败,我就可以立即中断它,处理你的失败(例如,回滚你的工作单元),并将错误返回给调用者,也许还需要添加信息。
一个可能的缺点是,跨几个不同的类进行错误处理是非常简单的,因此当进程失败时发生的定义很难从代码中推断出来。
不管怎样,这里没有单一的答案,您需要权衡这两种方法,有时还需要将它们结合起来。
关于您的示例,我看不到在流控制中使用异常的任何优势,特别是在"良好"(设计用于工作)场景中。
例外是对象是有原因的。还有一个原因是Java语言的设计者把所有EDCOX1,5个s分成2个主要类型:检查和未检查。
is it a good idea to rely on an
exception happening for certain
business logic to occur?
对。当然。你应该阅读"有效Java,第二版"的第9章。就在那里。解释得很好,在等你。
如果您处理的错误条件实际上是业务逻辑的一部分,那么可以使用异常。例如:
1 2 3 4 5 6 7 8 | try{ // register new user if(getUser(name) != null) throw new MyAppException("Such user already exists"); //other registration steps...... }catch(MyAppException ex){ sendMessage(ex.getMessage()); } |