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. OSG-3.4.0 简要说明(Readme)

    欢迎来到OpenSceneGraph(OSG)世界. Welcome to the OpenSceneGraph (OSG). 对于项目最新信息, 以及如何编译和运行库和示例的更多细节, 可以查看OS ...

  2. 微信支付JS API使用心得

    微信的接口真的很坑爹,只返回成功或失败,从来不会告诉你为什么失败.这个微信支付的js接口也是调了一个下午才成功,期间踩了不少坑,在这里总结一下,而且把支付接口封装成了一个js文件,这样以后调用就很方便 ...

  3. To fix sql server 2008 r2 Evaluation period has expired by change the key

    PTTFM-X467G-P7RH2-3Q6CG-4DMYB 数据中心版:PTTFM-X467G-P7RH2-3Q6CG-4DMYB   测试可用 开 发者 版:MC46H-JQR3C-2JRHY-XY ...

  4. Python之创建tuple

    tuple是另一种有序的列表,中文翻译为" 元组 ".tuple 和 list 非常类似,但是,tuple一旦创建完毕,就不能修改了. 同样是表示班里同学的名称,用tuple表示如 ...

  5. 数据结构———重载与模板(C++)

    相关信息 /* * * @subject 数据结构 * @author 信管1142班 201411671210 JJ lai * * @program 模板与重载 * */ 实验一: /* 要求如下 ...

  6. opencv 操作本地摄像头实现录像

    直接上代码: // demo1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...

  7. Linux按照时间查找文件

    linux按照时间查找文件 需要用到一个根据最后修改时间来处理的脚本. 前面有个有关find的基本用法,根据文件大小,类型什么的,这个是关于时间的.  linux 文件的三种时间(以 find 为例) ...

  8. spoj LCS

    初识后缀自动机: 推荐学习:http://blog.sina.com.cn/s/blog_7812e98601012dfv.html #include<cstdio> #include&l ...

  9. nginx -t "nginx: [warn] only the last index in "index" directive should be absolute in 6 "的问题解决

    修改完nginx的配置文件之后,执行nginx -t命令提示"nginx: [warn] only the last index in "index" directive ...

  10. http://www.itpub.net/thread-1778530-1-1.html

    http://www.itpub.net/thread-1778530-1-1.html