Error handling is important, but if it obscures logic, it's wrong.

Use Exceptions Rather Than Return Codes

Separate the normal operations with error handlings.

e.g.

Bad code:

public class DeviceController {
...
public void sendShutDown() {
DeviceHandle handle = getHandle(DEV1);
// Check the state of the device
if (handle != DeviceHandle.INVALID) {
// Save the device status to the record field
retrieveDeviceRecord(handle);
// If not suspended, shut down
if (record.getStatus() != DEVICE_SUSPENDED) {
pauseDevice(handle);
clearDeviceWorkQueue(handle);
closeDevice(handle);
} else {
logger.log("Device suspended. Unable to shut down");
}
} else {
logger.log("Invalid handle for: " + DEV1.toString());
}
}
...
}

Good code:

public class DeviceController {
...
public void sendShutDown() {
try {
tryToShutDown();
} catch (DeviceShutDownError e) {
logger.log(e);
}
}
private void tryToShutDown() throws DeviceShutDownError {
DeviceHandle handle = getHandle(DEV1);
DeviceRecord record = retrieveDeviceRecord(handle);
pauseDevice(handle);
clearDeviceWorkQueue(handle);
closeDevice(handle);
}
private DeviceHandle getHandle(DeviceID id) {
...
throw new DeviceShutDownError("Invalid handle for: " + id.toString());
...
}
...
}

Write Your Try-Catch-Finally Statement First

It is good practice to start with a try-catch-finally statement when you are writing code that could throw exceptions.

(本节中有关单元测试的讲解,没看明白,留待以后回顾再看。)

Use Unchecked Exceptions

Checked exceptions is an Open/Closed Principle violation.

(C# doesn't have checked exceptions.)

Provide Context with Exceptions

To determine the source and location of an error.

Mention the operation that failed and the type of failure.

Define Exception Classes In terms of a Caller's Needs

Most important concern: how they are caught.

In most exception handling situations, the work that we do is relatively standard regardless of the actual cause. So we can simplify our code considerably by wrapping the third-party APIs.

e.g.

Bad code:

ACMEPort port = new ACMEPort(12);
try {
port.open();
} catch (DeviceResponseException e) {
reportPortError(e);
logger.log("Device response exception", e);
} catch (ATM1212UnlockedException e) {
reportPortError(e);
logger.log("Unlock exception", e);
} catch (GMXError e) {
reportPortError(e);
logger.log("Device response exception");
}
finally {

}

Good code:

LocalPort port = new LocalPort(12);
try {
port.open();
}
catch (PortDeviceFailure e) {
reportError(e);
logger.log(e.getMessage(), e);
}
finally {

} public class LocalPort {
private ACMEPort innerPort;
public LocalPort(int portNumber) {
innerPort = new ACMEPort(portNumber);
}
public void open() {
try {
innerPort.open();
} catch (DeviceResponseException e) {
throw new PortDeviceFailure(e);
} catch (ATM1212UnlockedException e) {
throw new PortDeviceFailure(e);
} catch (GMXError e) {
throw new PortDeviceFailure(e);
}
}

}

Define the Normal Flow

Use the Special Case Pattern. Create a class or configure an object so that it handles a special case for you. When you do, the client code doesn't have to deal with exceptional behavior. That behavior is encapsulated in the special case object.

Don't Return Null

When we return null, we are essentially creating work for ourselves and foisting problems upon our callers.

If you are tempted to return null from a method, consider throwing an exception or returning a special case object instead. If you are calling a null-returning method from a third-party API, consider wrapping that method with a method that either throws an exception or returns a special case object.

e.g.

Bad code:

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

Good code:

List<Employee> employees = getEmployees();
for(Employee e : employees) {
totalPay += e.getPay();
} public List<Employee> getEmployees() {
if( .. there are no employees .. )
return Collections.emptyList();
}

Don't Pass Null

Conclusion

We can write robust clean code if we see error handling as a separate concern, something that is viewable independently of our main logic. To the degree that we are able to do that, we can reason about it independently, and we can make great strides in the maintainability of our code.

Clean Code–Chapter 7 Error Handling的更多相关文章

  1. Clean Code – Chapter 3: Functions

    Small Blocks and Indenting The blocks within if statements, else statements, while statements, and s ...

  2. Clean Code – Chapter 4: Comments

    “Don’t comment bad code—rewrite it.”——Brian W.Kernighan and P.J.Plaugher The proper use of comments ...

  3. TIJ——Chapter Twelve:Error Handling with Exception

    Exception guidelines Use exceptions to: Handle problems at the appropriate level.(Avoid catching exc ...

  4. Clean Code – Chapter 2: Meaningful Names

    Use Intention-Revealing Names The name should tell you why it exists, what it does, and how it is us ...

  5. Clean Code – Chapter 6 Objects and Data Structures

    Data Abstraction Hiding implementation Data/Object Anti-Symmetry Objects hide their data behind abst ...

  6. Clean Code – Chapter 5 Formatting

    The Purpose of Formatting Code formatting is about communication, and communication is the professio ...

  7. setjmp()、longjmp() Linux Exception Handling/Error Handling、no-local goto

    目录 . 应用场景 . Use Case Code Analysis . 和setjmp.longjmp有关的glibc and eglibc 2.5, 2.7, 2.13 - Buffer Over ...

  8. Erlang error handling

    Erlang error handling Contents Preface try-catch Process link Erlang-way error handling OTP supervis ...

  9. Error Handling

    Use Exceptions Rather Than Return Codes Back in the distant past there were many languages that didn ...

随机推荐

  1. mysql更改默认存储引擎

    在mysql的官网上看到在mysql5.5以上的版本中已经更改了默认的存储引擎,在5.5版本以前是Myisam以后是Innodb. InnoDB as the Default MySQL Storag ...

  2. 关于NRW算法(Quorum算法)

    在分布式系统中,冗余数据是保证可靠性的手段,因此冗余数据的一致性维护就非常重要.一般而言,一个写操作必须要对所有的冗余数据都更新完成了,才能称为成功结束.比如一份数据在5台设备上有冗余,因为不知道读数 ...

  3. logback使用笔记

    三大主要元素 looger:记录日志 appender:输出目的地 layout:输出格式 必要步骤: 一.引入包: import org.slf4j.Logger; import org.slf4j ...

  4. C语言基础知识-循环结构

    用while打印出1~100之间7的倍数    int i = 1;     while循环是当条件表达式的结果为真时,执行大括号里面的循环体,重复执行直到条件表达式的结果为假时结束循环.     w ...

  5. JQuery插件,傻傻分不清!

    不多说,直接上代码! 第一种 extend <!-- extend 扩展jQuery,其实就是增加一个静态方法 -->         $.extend({            sayH ...

  6. 7.MVC框架开发(创建层级项目)

    在一个项目比较大的时候,就会有多个层级项目 1)在项目中选定项目右建新建区域(新的层级项目),项目->右键->添加->区域,构成了一套独立的MVC的目录,这个目录包括Views,Co ...

  7. MVC-Model数据注解(三)-Remote验证的一个注意事项

    首先,一般来说对于一个属性的验证可能需要不止一个的远程验证,比如对于用户名来说,我们需要对于它的长度做一些限制,这个可以通过StringLength特性来解决:同时还需要验证用户名不能重复,这个就需要 ...

  8. Windows store app Settings 的 应用 ( viewmodel + windows.storage)

    1.在首页 加入 一个元素(加下滑线的).此元素绑定了两个属性 <!DOCTYPE html> <html> <head> <meta charset=&qu ...

  9. WebKit Web Inspector增加覆盖率分析和类型推断功能

    WebKit中的Web Inspector(Web检查器)主要用于查看页面源代码.实时DOM层次结构.脚本调试.数据收集等,日前增加了两个十分有用的新功能:覆盖率分析和类型推断.覆盖率分析工具能够可视 ...

  10. Linux用户行为日志审计

    http://my.oschina.net/xiangpang/blog/532999 http://my.oschina.net/chaichuan/blog/508494 http://my.os ...