【发布时间】:2016-06-10 19:15:03
【问题描述】:
重新思考具有 null /empty 处理场景的设计模式
类似下面的函数
function(customerid){
customer=findcustomerbyId(customerid)-->findcustomer
list<Transactions> accounts=getNewTransactions(customer)-->findtransactions
foreach{if(transaction.isGasTransaction()){send(event)..if()sendevent()}}-->send events
}
现在的问题是,每当我们期望一个函数的返回值时,它应该是一个空值吗?或者如果数据库找不到值应该抛出异常。
抛出空值会迫使您编写代码来处理空值/空列表。这将增加 if-else 块,并且您的 junit 案例也会增加(成正比)。抛出异常将迫使您采用不同的编程风格,并且您需要一些预期异常的测试用例。
类似 spring-jdbc 模板 queryForObject 如果 db 中没有值则抛出异常。(预期为 1 但得到 0)
这里的正确方向是什么。更多例外?或像其他 null 替代品一样使用 Optionsljava-8 或使用 nulls?
我们可以在不同的场景中平衡这些风格:)
所以对于一个 rest-api 项目,我认为抛出异常会很好,如果你有一个全局异常处理程序(如控制器建议)的原因,你可以在你的代码中处理异常而不用担心方法堆栈处理空检查/空检查,因为异常在通知级别被捕获并相应地传播。
***这是思考一个方向而不是讨论哪个最好*****
【问题讨论】:
-
您的问题似乎是一个风格或最佳实践问题。设计模式是完全不同的、更具体的东西。
-
是的,我同意风格与最佳实践,我确实在这个项目中选择了例外风格,但是新的 ppl 加入呢,这是一个最佳实践,让 ppl 很容易理解。正如我解释的那样,在我的场景中不需要 try catch,因为我有一个全局异常处理程序来返回自定义的 e.message 作为服务的响应。以便稍后进行调试
-
在我看来,您想使用异常来进行流量控制/信令。但是,恕我直言,异常应该按原样使用:异常,表示出现问题。如果在测试期间缺少数据意味着确实有问题,那么在我看来抛出异常是可以的。但通常您应该重新审视您的设计,并考虑在什么情况下应该返回哪些方法,尤其是 null 值对您意味着什么。在某些情况下,空对象也可以。想想什么会减少对代码的污染。同样使用全局异常处理程序看起来像是一种设计气味
-
这是一项严肃的基础工作,需要深思熟虑:P 在我的工作场所,我们也在为此苦苦挣扎,因为人们对此有不同的看法。如果您在团队中编程:与他们交谈并讨论每种方法的利弊。做出决定并坚持下去!如果您认为在任何地方使用异常都可以,那没关系,只要您不中途改变主意并开始使用空对象即可。
-
我明白了这一点,这在我的团队中进行了长时间的辩论。我倾向于例外,因为我的这种情况没有意义。使用空数据作为逻辑中的下一步将不会执行如果有空值。(90% 的时间 ppl 不期望空值,例如:- 带有 id 的 getCustomer,验证信用卡密码等)。任何空值检查都是好的,但不是必需的,因为这只是为了增加 junit 覆盖率和如果某些值为空,服务调用将不会达到此级别
标签: java design-patterns junit nullpointerexception