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 ...
随机推荐
- (用微信扫的静态链接二维码)微信native支付模式官方提供的demo文件中的几个bug修正
native支付模式一demo(用微信扫的静态链接二维码)BUG修复,一共4个BUG 1.native_call_qrcode.php这个文件中的代码无法生存native支付的短地址2.WxPayPu ...
- 字符编码笔记:ASCII,Unicode和UTF-8【转载】
作者: 阮一峰 日期: 2007年10月28日 今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. 结果,这个问题比我想象的复杂,从午饭后一直看到晚上9点,才算初步 ...
- Nodejs初学者福音
Nodejs+Express+MongoDb 搭建个人博客 001 我喜欢把任务或者工作分解成工作流来完成,如下,后面将会按照流程来详述,希望能为Nodejs初学者及推广Nodejs做出些努力. n ...
- 移动端Reactive Native轮播组件
移动端Reactive Native轮播组件 总结下这段时间学习reactive native的一些东西,我们来认识一下,被炒得这么火的rn,究竟是个什么东西,以及如何去搭建自己的demo. reac ...
- 解决npm安装模块时 npm err! registry error parsing json
最近还真是点背,从yeoman生成一个react项目或是github上克隆一个项目,在npm install的时候, 一直报npm err! registry error parsing json(就 ...
- Grails的redirect无法跳转时的一个可能原因
由于controller的命名一般首字母大写,如Login 此时如 class LoginController { def index = { redirect(action:Login, param ...
- VC项目配置基础以及快捷键(收藏)
来自http://blog.csdn.net/phunxm/article/details/5082488 一.IDE基础配置 1.字体 VC6中“Tools→Options→Format→Font” ...
- poj 2559 Largest Rectangle in a Histogram (单调栈)
http://poj.org/problem?id=2559 Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 6 ...
- 来自内部的XSS攻击的防范
来自内部的XSS攻击的防范 引入:前面我们分2篇文章分别探讨了来自外部的XSS攻击和来自内部的XSS攻击,现在我们来专门探讨如何防范来自内部的XSS攻击. 实践:其实从 http://www.2cto ...
- mysql中实现行号,oracle中的rowid
mysql中实现行号需要用到MYSQL的变量,因为MySql木有rownumber. MYSQL中变量定义可以用 set @var=0 或 set @var:=0 可以用=或:=都可以,但是如果变量用 ...