错误处理很重要,但如果它搞乱了代码逻辑,就是错误的做法。
一、使用异常而非返回码
遇到错误时,最好抛出一个异常。
二、先写Try-Catch-Finally语句
try代码就像是事务,catch代码块将程序维持在一种持续状态,物流try代码块中发生了什么均如此。在编写可能抛出异常的代码时,最好先写出try-catch-finally语句。
尝试编写强行抛出异常的测试,再往处理器中添加行为,使之满足测试要求。结果就是你要先构造try代码块的事务范围,而且也会帮助你维护好该范围的事务特征。
三、使用不可控异常
可控异常的代价就是违反开放/闭合原则。如果你在方法中抛出可控异常,而catch语句在三个层级之上,你就得在catch语句和抛出异常处之间的每个方法签名中声明该异常。这意味着对软件中较低层级的修改,都将波及较高层级的签名。修改好的模块必须重新构建、发布,即便它们自身所关注的任何东西都没改动过。
四、给出异常发生的环境说明
应创建信息充分的错误信息,并和异常一起传递出去
五、依调用者需要定义异常类
对错误分类有很多方式,可以依其来源分类。在程序中定义异常类时,最重要的考虑应该是它们如何被捕获。
将第三方API打包是个良好的实践手段。当你打包一个第三方API,你就降低了对它的依赖:未来你可以不太痛苦地改用其他代码库。
六、定义常规流程
特例模式(SPECIAL CASE PATTERN),创建一个类或配置一个对象,用来处理特例。
七、别返回null值
容易引发错误的做法,第一项便是返回null值。如果打算在方法中返回null值,不如抛出异常,或是返回特例对象。
八、别传递null值
在方法中返回null值是糟糕的做法,但将null值传递给其他方法就更糟糕了。除非API要求你向他传递null值,否则就要尽可能避免传递null值。
九、小结
整洁代码是可读的,但也要强固。可读与强固并不冲突。如果将错误处理隔离看待,独立于主要逻辑之外,就能写出强固而整洁的代码。做到这一步,我们就能单独处理它,也极大地提升了代码的可维护性。