《代码整洁之道》读书笔记(五)之错误处理

错误处理很容易将代码搞凌乱,这里介绍处理错误代码的一些技巧,努力编写一个既整洁又强固的代码。

1. 使用异常而非返回码

返回返回码的问题在于,它们搞乱了调用者代码。调用者必须在调用之后即可检查错误。不幸的是,这个步骤很容易被遗忘。所以,遇到错误时,最好抛出一个异常。

2. 先写Try-Catch-Finally语句

在编写可能抛出异常的代码时,最好先写出try-catch-finally语句。这能帮你定义代码的用户应该期待什么,无论try代码块中执行的代码出什么错都一样。

3. 使用不可控异常(unchecked exception)

可控异常有利有弊。使用可控异常的代价是违反开放/闭合原则。如果你在方法中抛出可控异常, 而catch语句在三个层级之上,你就得在catch语句和抛出异常处之间的每个方法签名中声明该异常。这意味着对软件中较低层级的修改,都将波及较高层级的签名。修改好的模块必须重新构建、发布,即便它们自身所关注的任何东西都没改动过。

4. 给出异常发生的环境说明

你抛出的每个异常,都应当提供足够的环境说明,以便判断错误的来源和处所。虽然可以从异常里追寻到Java stack trace,但是这个无法告诉你该失败操作的初衷。

因此,应当创建信息充分的错误消息,并和异常一起传递出去。在消息中,包括失败的操作和失败类型。

5. 依调用者需要定义异常类

当我们定义异常类时,最重要的考虑应该是它如何被捕获。

当底层抛出很多异常,但是我们并不需要这么细的划分时候,我们可以通过定义自己的异常,重新抛出我们的异常。另外,针对第三方API,我们可以对其的方法和异常进行一层封装,方便后续灵活替换。

6. 别返回null值

很多代码需要不断的检查返回值是否为null。这种代码糟糕透了。返回null值基本上是给自己增加工作量,也是在给调用者添乱。只要有一处没有检查null值,程序就会失控。

设想有这么一段代码:


List employees = getEmployees();
if (employees != null) {
    for (Employee e : employees) {
        totalPay += e.getPay();        
    }    
}

现在getEmployees()可能会返回null,但是否一定要这么做呢,如果修改getEmployees(),返回空列表,就能使代码整洁起来:

List employees = getEmployees();
for (Employee e : employees) {
    totalPay += e.getPay();        
}    

所幸Java有Collections.emptyList()方法,该方法返回一个预定义的不可变列表,可用于这种目的:


public List getEmployees() {
    if ( .. there are no employees ..) {
        return Collections.emptyList();
    }
    ...
}

7. 别传递null值

在方法中返回null值是糟糕的做法,但将null值传递给其他方法就更糟糕了。除非API要求你向它传递null值,否则就要尽可能避免传递null值。

你可能感兴趣的:(《代码整洁之道》读书笔记(五)之错误处理)