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 ...
随机推荐
- codeforces 8VC Venture Cup 2016 - Elimination Round C. Lieges of Legendre
C. Lieges of Legendre 题意:给n,m表示有n个为2的倍数,m个为3的倍数:问这n+m个数不重复时的最大值 最小为多少? 数据:(0 ≤ n, m ≤ 1 000 000, n + ...
- boost linux 下安装
1. 在boost 官网 http://www.boost.org/doc/libs/ 下载最新的boost 安装包 2. 解压至 /usr/local/ 目录下 3. cd /usr/local/b ...
- Oracle删除所有表
Oracle 清理用户所有的表 PLSQL中执行语句 select 'drop '||object_type||' '||object_name||';' from user_objects; 结果集 ...
- 使用Sass预定义一些常用的样式,非常方便(转)
SS预处理技术现在已经非常成熟,比较流行的有Less,Sass,Stylus,在开发过程中提升我们的工作效率,缩短开发时间,方便管理和维护代码,可以根据自己的喜好选择一款自己喜欢的工具开发,使用很接近 ...
- BZOJ 3990 [SDOI 2015] 排序 解题报告
这个题哎呀...细节超级多... 首先,我猜了一个结论.如果有一种排序方案是可行的,假设这个方案是 $S$ . 那么我们把 $S$ 给任意重新排列之后,也必然可以构造出一组合法方案来. 于是我们就可以 ...
- 关于对js的this的几点理解
四种不同模式小调用的指向 1.函数调用模式的时候,this指向window 2.方法调用模式的时候,this指向方法所在的对象 3.构造函数模式的时候,this指向新生成的实例 4.apply/cal ...
- 【win8技巧】应用商店里面如何搜索应用app
win8应用商店搜索app软件的技巧 1.组合键 WIN+C 打开屏幕最右边磁条 2.点击搜索,输入你想搜的软件名称,里面会列出你已经安装的app或者你点击下面的应用商店选项,就可以搜索互联网上应用商 ...
- ubuntu使用中的一些问题
ubuntu如何修改计算机名? sudo gedit /etc/hostname 如何查看ubuntu操作系统位数 方法1: #查看long的位数,返回32或64 getconf LONG_BIT 方 ...
- 8. Unity异常警告错误处理方法
一. The AnimationClip 'cube1_anim' used by the Animation component 'Cube1' must be marked as Legacy. ...
- RxJava开发精要6 – Observables组合
原文出自<RxJava Essentials> 原文作者 : Ivan Morgillo 译文出自 : 开发技术前线 www.devtf.cn 转载声明: 本译文已授权开发者头条享有独家转 ...