Clean Code–Chapter 7 Error Handling
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的更多相关文章
- Clean Code – Chapter 3: Functions
Small Blocks and Indenting The blocks within if statements, else statements, while statements, and s ...
- Clean Code – Chapter 4: Comments
“Don’t comment bad code—rewrite it.”——Brian W.Kernighan and P.J.Plaugher The proper use of comments ...
- TIJ——Chapter Twelve:Error Handling with Exception
Exception guidelines Use exceptions to: Handle problems at the appropriate level.(Avoid catching exc ...
- 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 ...
- Clean Code – Chapter 6 Objects and Data Structures
Data Abstraction Hiding implementation Data/Object Anti-Symmetry Objects hide their data behind abst ...
- Clean Code – Chapter 5 Formatting
The Purpose of Formatting Code formatting is about communication, and communication is the professio ...
- 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 ...
- Erlang error handling
Erlang error handling Contents Preface try-catch Process link Erlang-way error handling OTP supervis ...
- Error Handling
Use Exceptions Rather Than Return Codes Back in the distant past there were many languages that didn ...
随机推荐
- CGAL Manual/tutorial_hello_world.html
Hello World Author CGAL Editorial Board 本教程是为知道C++和几何算法的基本知识的CGAL新手准备的.第一节展示了如何特化点和段CGAL类,以及如何应用几何谓词 ...
- mysql(转)
/* 启动MySQL */net start mysql /* 连接与断开服务器 */mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限验证登录MySQL */mysqld ...
- javascript和jquery动态创建html元素
1.javascript创建元素 创建select var select = document.createElement("select"); elect.opti ...
- FZU 2140 Forever 0.5
Problem 2140 Forever 0.5 Accept: 36 Submit: 113 Special JudgeTime Limit: 1000 mSec Memory ...
- cocos-html5 JS 写法基础 语言核心
转载:http://blog.csdn.net/leasystu/article/details/18735797 cocos2dx 3.0 js继承:John Resiq的继承写法解析 CCClas ...
- 关于安装完Node.js 出现node is not dedined 问题
今天想来接触下Node.js 神奇 怀着揣揣的心 从官网下载了windows 的64位mis版本 几个下一步就顺利安装完毕了 接着跟着新手教程走 不懂教程里的 苹果shell 是什么 反正就是检 ...
- virsh console使用方法
How to use virsh console virsh 是libvirt 开源函数库中的一个命令行工具,用来在命令行下通过libvirt发布管理虚拟机的各种命令,现在介绍一下其中一个命令的使用方 ...
- Linux 启动参数介绍
Linux 启动参数介绍 取自2.6.18 kernel Documentation/i386/boot.txt 文件中介绍 vga= 这里的不是一个整数(在C语言表示法中,应是十进制,八进制或者十六 ...
- tcpdump dump 网络流量
tcpdump dump 网络流量 描述: Tcpdump 打印一个包的内容的描述在一个网络接口 匹配布尔值表达式 它也可以运行使用-w flag, 这样会保存包的数据到一个文件用于后面分析, 使用- ...
- android:process为耗资源操作指定一个新进程
当有一些耗费内存比较多的操作时,可以通过android:process指定一个新的进程.保证程序运行. 例如: 一个后台长期运行的service: <service android:name=& ...