0%

代码整洁之道 - 错误处理

错误处理很重要,但是如果它搞乱了代码逻辑,就是错误的做法

使用异常而非返回码 Use Exceptions Rather Than Return Codes

  • 将逻辑和错误处理隔离

先写 try-catch-finally 语句 Write Your Try-Catch-Finally Statement First

异常的妙处在于:它们在程序中定义了范围,执行 try-catch-finally 语句中 try 部分的代码时,你是在表明可随时取消执行,并在 catch 语句中接续

在某种意义上,try 代码块就像是 事务

  • 最好先写出 try-catch-finally 代码块,能帮你定义该代码的用户 应该期待什么

尝试编写强行抛出异常的测试,再往处理器中添加行为,使之满足测试要求

使用未检异常 Use Unchecked Exceptions

  • Java 中存在已检异常和未检异常,优先使用未检异常

  • 已检异常有个问题是会得到:一个从软件最底端贯穿到最顶端的修改链

给出异常发生的环境说明 Provide Context with Exceptions

  • 应创建信息充分的错误消息,并和异常一起传递出去

  • 在消息中,应包括失败的操作和失败类型

依调用者需要定义异常类 Define Exception Classes in Terms of a Caller’s Needs

  • 将第三方打包是个良好的实践手段

    • 可以降低对它的依赖,未来可以不太痛苦地改用其他代码库

    • 在测试时,有助于模拟第三方调用,使用 Moq

    • 不必绑死在某个特定厂商的 API 设计上,可以定义自己感觉舒服的 API

定义常规流程 Define the Normal Flow

有时可以用特例模式(Special Case Pattern)处理特例,创建一个类或配置一个对象,把异常行为封装到这个特例对象中

别返回 null 值 Do not Return Null

别传递 null 值 Do not Pass Null

在大多数语言中,没有良好的办法应对由调用者意外传入的 null 值,恰当的做法是 禁止传入 null 值

  1. 可以用断言 Assertion

  2. 可以检查传入参数是否为 null 并抛出自定义异常

小结 Conclusion

  • 整洁代码既要可读,也要强固

  • 可读与强固并不冲突

  • 将错误处理隔离看待,独立于主要逻辑之外,就能写出强固而可读的代码

  • 这样可以极大地提升代码的可维护性