`
feikiss
  • 浏览: 99920 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

clean-code: 错误处理

阅读更多
下面就Clean code 中关于如何优雅的处理一些错误代码总结的一些技巧和思路。

1、使用异常而非返回码

请看下面的代码清单, DeviceController.java
public class DeviceController {
	...
	public void sendShutDown(){
		//Check the state of the device
		if(handle != DeviceHandle.INVALID){
			//Save the device status to the record field
			DeviceRecord record = retrieveDeviceRecord(handle);
			//If not suspended, shut down
			if(record.getStatus() != DEVICE_SUSPENDED){
				pauseDevice(handle);
				clearDeviceWorkQueue(handle);
				closeDevice(handle);
			}else {
				logger.log("Device suspende.");
			}
		} else{
			logger.log("invalid handle for:" + DEV1.toString());
		}
	}
	...
}

我想大家在项目中都碰到过类似的嵌套检查。这类手段的问题在于,他们搞乱了调用者代码。调用者必须在调用之后即可检查错误。不幸的是,这个步骤很容易被遗忘。所以,遇到错误时,最好抛一个异常。调用代码很整洁,其逻辑不会被错误处理搞乱。
下面的代码清单展示了方法中遇到错误时抛出异常的情形。
代码清单: DeviceController.java(采用异常处理)
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 getHanle(DeviceID id){
		...
		throw new DeviceShutDownError("invalid handle for: " + id.toString());
		...
	}
	
	private DeviceRecord retrieveDeviceRecord(DeviceHandle handle){
		...
		throw new DeviceShutDownError("Device suspended.");
		...
	}
	...
}

这段代码就整洁了很多,当然多出了一些异常类,但这是不可缺少的。。。
现在,对两个元素设备的关闭算法和错误处理已经被隔离了,我们可以查看其中任一元素,并分别理解和处理他们,而不必去修改业务逻辑代码。

2、根据调用者需要来定义异常类。
当我们在应用程序中定义异常时,最重要的考虑应该是“他们如何被捕获”。
来看一个很常见的代码。
代码清单:

	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",e);
	}finally {
		...
	}

可以看到,语句中包含了大量的重复代码,这并不奇怪。因为我们得记录错误,确保能继续工作。
在本例中,既然我们知道我们所作的事儿不外如此,就可以通过打包调用API,确保它返回通用异常类型,从而简化代码。
代码清单:
LocalPort port = new LocalPort(12);
	try{
		port.open();
	}catch (PortDeviceFailure e){
		reportError(e);
		logger.log(e.getMessage(),e);
	}finally{
		...
	}
	
LocalPort类就是个简单的打包类,捕获并翻译由ACMEPort类抛出的异常:	
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);
		}
	}
	...
}

类似我们为ACMEPort定义的这种打包类非常有用,这也可以看作是对第三方API做了一个代理,实际上,将第三方API打包是个良好的实践手段。当打包一个第三方API,就降低了对它的依赖:未来你可以不太痛苦地改用其他代码库。而且在测试自己的代码时,打包也有助于模拟第三方调用。
3、别返回null值
对于NullPointerException,想必大家都熟悉得不能再熟悉了。那么如何尽量避免空指针异常呢?其一就是尽量避免返回null值,可以用一个特例对象来代替。如果是调用第三方API返回null值,可以在新方法中抛出异常或返回特例对象,比如在Java中如果返回的是一个list,如果返回为null,完全可以用Cloolections.emptyList()来代替,这样调用者就不必来检查获取的结果是否为null了。
4、别传递null值,在大多数编程语言中,没有良好的方法能对付由调用者意外传入的null值,事已至此,恰当的做饭就是禁止传入null值。

以上代码是阅读Clean code第七章后做的一些小笔记,大家可以共同学习。
1
0
分享到:
评论

相关推荐

    clean-code-javascript

    Martin所著的《Clean Code》一书中的原则,将其适应于JavaScript语言环境。这不仅仅是一份样式指南,更是一种关于如何编写可读性强、可重用性高且易于重构的JavaScript软件的方法论。 #### 二、变量命名 在编写...

    clean-code:干净的代码说明

    在"clean-code-main"这个压缩包中,我们可以期待找到一系列按照书中的章节结构编排的.md文件,每个文件可能对应书中的一节或一个主题。以下是对《干净的代码》中关键知识点的详细解释: 1. **命名约定**:好的命名...

    Everything-about-Clean-Code:该存储库包含与阅读和理解Robert C. Martins的“ Clean Code”有关的所有内容。

    6. **错误处理**:不应忽视异常和错误处理,应明确处理可能出现的问题,而不是简单地忽略它们。 7. **测试驱动开发(TDD)**:通过先写测试后写代码的方式,确保代码满足需求,同时提高了代码质量。 在Java开发中,...

    fundamentos-em-c-sharp-com-clean-code:带有简洁代码的免费 C# 基础课程

    6. 错误处理:使用异常处理代替返回错误代码,提高代码的可维护性。 7. 编写可测试的代码:模块化设计,使代码易于单元测试,确保其正确性。 三、C#高级特性 1. LINQ(Language Integrated Query):提供了一种在...

    Clean-Code(JAVA必看的一本书非常好)

    4. **错误处理**:避免使用空指针异常(NullPointerException)、数组越界等常见的编程错误。书中建议积极检查并处理这些情况,而不是依赖异常处理。 5. **设计模式**:《Clean Code》讨论了多种设计模式,如工厂...

    clean-code-javascript.pdf 代码整洁的 JavaScript

    《代码整洁的JavaScript》一书将软件工程中的“Clean Code”原则应用于JavaScript编程,以帮助开发者编写可读性强、易于重用及重构的代码。本书并不是传统意义上的代码风格指南,而是围绕着一系列软件工程的最佳实践...

    Clean-Code-in-Python-Second-Edition:[Packt]发布第二版Python中的Clean Code

    4. **错误处理**:深入探讨了异常处理,鼓励使用特定的异常类型,并避免使用通用的`except`,以提高错误处理的精确性和可读性。 5. **代码组织**:讲解了模块和包的组织结构,如何通过合理的划分来提高代码的可重用...

    go-clean-code:罗伯特·C·马丁(Robert C. Martin)用“ Go(GoLang)”写的“清洁代码”一书中的示例[必须阅读!]

    清理代码 罗伯特·C·马丁(Robert C. Martin)用“ Go(GoLang)”写的“清洁代码”一书中的示例[必须...错误处理 界线 单元测试 *班 系统篇 紧急情况 并发 不断完善 * JUnit内部 重构SerialDate 嗅觉和启发式 *待定

    clean-code-quotes:鲍勃叔叔的“干净代码”在JSON中的引号

    4. **错误处理**:对可能出现的错误进行预防和处理,而不是忽略它们。 5. **测试**:编写自动化测试以验证代码功能,确保质量。 在JSON上下文中,这些原则体现为: 1. **明确性**:使用有意义的键名,避免模糊不清...

    Clean-Code-Practice:用C#编写的简洁代码示例

    4. **错误处理**: - 使用异常处理代替返回错误代码,使代码流更直观。 - 抛出有意义的异常类型,提供足够的上下文信息,便于调试。 - 不要捕获所有异常,除非有明确的恢复策略,否则应该让上层处理或记录。 5. ...

    Clean-Code-in-Python:Packt发布的Python中的Clean Code

    在所有这些领域中,经验丰富的专业人员都可以找到由于代码错误而导致的效率低下,问题和其他危险的示例。 阅读本书之后,读者将了解这些问题,更重要的是,如何解决这些问题。 本书涵盖了以下激动人心的功能:设置...

    clean-code-:phầnmềmtínhlương

    《clean-code-:phầnmềmtínhlương》是一个关于使用Java进行清洁代码编程实践的项目。在软件开发中,编写清晰、可读性强的代码对于团队协作和项目的长期维护至关重要。本项目旨在教授如何遵循"Clean Code"原则来...

    Clean-code-rest-model:该代码与技术无关,而是与长期支持和扩展的工作流的体系结构有关

    5. **错误处理**: 不要忽视错误,而是应正确处理它们,提供有用的错误信息。 6. **测试**: 编写测试用例以确保代码质量,单元测试和集成测试是Clean Code的重要组成部分。 接下来,REST(Representational State ...

    clean-code-booknote:记录clean-code的读书笔记

    5. **错误处理**:避免使用全局异常捕获,而是应该在可能出现错误的地方进行处理。使用异常来表示异常情况,而正常的控制流则应该通过返回值来实现。 6. **测试驱动开发(TDD)**:TDD是一种编程实践,先写测试,再...

    clean-magento:测试技能magento 2

    3. **静态代码分析**:Magento 2 提供了代码审核工具,如 Magento Code Quality Tools,用于检查代码风格、编码规范和潜在的错误,有助于保持代码质量。 4. **性能测试**:性能测试是评估 Magento 2 商店在高负载下...

    Android-Clean-Architecture:这是一个使用MVP + Dagger 2 + RX + Retrofit = Clean Android Code base的示例应用程序Bob叔叔的干净架构方法

    它可以将多个操作组合在一起,并提供错误处理、背压和取消订阅等高级功能。 **Retrofit** Retrofit 是一个网络请求库,它允许开发者通过简单的接口定义 RESTful API。Retrofit 将网络调用转换为 Java 方法调用,...

    clean-commit-action:Github防止错误的git commit消息的动作

    [WIP]清洁承诺行动Clean-commit-action是防止不良git commit消息的简单操作。为什么提交消息起着非常重要的作用,并且是在很长一段时间后去查看提交内容的最佳方式,可以与将来的开发人员以及我们自己通信。 我们...

    Python简明教程

    - 捕获并处理异常。 - 示例: ```python try: result = 10 / 0 except ZeroDivisionError: print("Cannot divide by zero") ``` - **引发异常**: - 主动抛出异常。 - 示例: ```python raise ...

    clean-code-s1e1

    6. **错误处理**:使用`try...catch`语句捕获和处理错误,而不是依赖于全局异常处理。错误对象应包含足够的信息,便于调试。 7. **模块化**:利用ES6的模块系统(`import`和`export`)组织代码,每个模块负责一个...

    Write Clean Code Write Clean Code Write Clean Code Write Clean Code

    书中的内容涵盖了C编程的多个核心领域,包括基本语法、错误处理、内存管理、数据结构、算法优化以及软件设计原则等。以下是对这些知识点的详细阐述: 1. **基本语法**:C语言的基础,包括变量声明、运算符、流程...

Global site tag (gtag.js) - Google Analytics