《代码整洁之道 》第七章 错误处理

第七章 错误处理

应该弄清楚错误处理与代码简洁的关系,许多程序代码完全由错误处理所占据的话,是非常不好的。因为到处都是凌乱的代码。

7.1 使用异常而非返回码

很久以前,很多语言都不支持异常。所以当时是你要么设置一个错误标识,要么返回给调用者检查的错误码。
image.png

7.2 先写Try-Catch-Finally语句

异常的妙处之一,是因为他在程序里定义了一个范围,某种意义上来说,try代码块就像是事物,catch代码块将程序维持在一种持续状态,无论try代码块发送什么,都是如此。
所以在写可能抛异常的代码时,最好先写Try-Catch-Finally语句。
例子:我们要编写访问某个文件并读出一些序列化对象的代码。
单元测试:文件不存在将得到一个异常
image.png

7.3 使用不可控异常

可控异常看起来很美好,但是他的代价是违反了开闭原则。
如果你在方法中抛出可控的异常,而catch语句在三个层级之上,你就得在catch语句和抛出异常处之间的每个方法签名中声明改异常。这意味着对软件中较低层级的修改,都将波及较高层级的签名。修改好的模块必须 重新构建、发布,即便它们自身所关注的任何东西都没改动过。
以某个大型系统的调用层级为例。顶端函数调用它们之下的函数,逐级向下。假设某个 位于最底层级的函数被修改为抛出一个异常。如果该异常是可控的,则函数签名就要添加throw 子句。这意味着每个调用该函数的函数都要修改,捕获新异常,或在其签名中添加合 适的throw 子句。以此类推。最终得到的就是一个从软件最底端贯穿到最高端的修改链!封 装被打破了,因为在抛出路径中的每个函数都要去了解下一层级的异常细节。既然异常旨在 让你能在较远处处理错误,可控异常以这种方式破坏封装简直就是一种耻辱。

7.4 给出异常发生的环境说明

你抛出的每个异常,都应当提供足够的环境说明,以便判断错误的来源和处所。

7.5 依调用者需要定义异常类

对错误分类有很多方式,可以依其来源分类。不过最重要的考虑应该是他们如何被捕获。

下面的代码是覆盖了所有可能抛出的异常
image.png

7.6 定义常规流程

如果做到在业务逻辑和错误处理代码之间有良好的隔离。大量的代码就会变得整洁朴素。
然而,这样做却把错误检测推到了程序的边缘地带。你 打包了外部API以抛出自己的异常,你在代码的顶端定义了一个处理器来应付任何失败了的运 算。在大多数时候,这种手段很棒,不过有时你也许不愿这么做。
例子: 如果消耗了餐食,则计入总额中。如果没有消耗,则员工得到当日餐食补贴。异常打断了业务逻辑。
image.png

7.7 别返回null值

如果程序调用方法,老是在判断是否为null,真是糟糕透了。
image.png

7.8 别传递null值

你传递null,被调用者可能就得判断你的参数了,也是难看。
image.png

7.9 小结

整洁代码是可读的,但也要强固。可读与强固并不冲突。如果将错误处理隔离看待,独立于主要逻辑之外,就能写出强固而整洁的代码。做到这一步,我们就能单独处理它,也极 大地提升了代码的可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值