空指针检查就能让程序更稳定吗?

 对空指针的大量检查虽然有其必要性, 但这种做法如果被滥用, 很容易把程序错误藏起来, 直到被用户发现为止, 而此时issue的现场已经离rootcause很遥远了.
这就导致了查错困难和发现bug时责任不清.

如果发现系统中到处都是空指针检查, 有理由感到沮丧, 并担心系统的稳定性和维护成本.
对空指针的严密检查其实是不得已而为之, 并不是说这就是好的编程风格了.

每一个方法在调用其他方法的时候, 都要尽量确保自己传过去的参数是正确的, 这是调用者的义务. 被调用者要求所有的参数合法, 无需做某些校验, 这是被调用者的权利, 被调用者在享受这个权利的同事, 当然也要尽到自身的义务, 提供恰当的调用结果, 不论是返回值, 副作用, 或异常.

在Spring源码中经常看到断言, 就是契约式编程的范例.  这样的系统才往往是robust的; 那种满是空指针检查的project看似严密, 其实最容易改出问题.
比如吃饭,  判断一个东西能不能吃, 是大脑的责任; 判断一个东西能不能消化, 是消化系统责任; 不能让厕所去判断一个东西能不能吃, 能不能消化.

那么究竟什么时候检查参数有效性呢? 如果被调用者在参数不合法的时候也能从错误中恢复并提供有意义的结果, 那就检查参数. 如果不能提供有意义的结果, 那就无需检查.

比如查询PriceMap的时候, 如果quantity为空, 其实也没有问题,  此时可以检查quantity数组, 如果为空则构建一个数组, 初始化每个数组元素为1, 就能从错误的边缘恢复.

如果productNo数组为空, 虽然这暗示上游程序不严密(也有可能是用了空对象模式),  但我们也完全可以从中恢复, 此时返回一个空的PriceMap就行是了. 所以, 如果因为quantity数组或者productNo数组为空而导致issue, 我们可以大致认为是被调用者的代码有问题.

但是, 如果整个参数对象PriceCriteria都为空呢? 这种情况是绝对不容许的, 因为这代表上游程序有严重错误. 所以不需检查PriceCriteria是否为空,直接使用就是了. 这样的话, 上游程序的错误可以尽快被发现. 如果非要检查PriceCriteria是否为空, 在为空时返回空的PriceMap, 就是用纸把火包起来.

 

你可能感兴趣的:(空指针检查就能让程序更稳定吗?)