`
禹爸爸
  • 浏览: 80198 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

异常处理策略与重构

阅读更多

异常处理策略

系统异常可以分为两大类:业务类异常技术类异常。顾名思义,业务类异常可以理解为在进行业务逻辑处理时,出现的异常。如创建客户订单时,发现没有为这个客户设置价格;取款时,取款金额大于帐户余额等。

技术类异常就更好理解了,这一层是与技术人员相关的,对系统使用者而言,应该是透明的。如无法正确连接数据库;访问数组或是列表时,索引超出范围;进行计算时,除数为零等。

 

针对不同类类型的异常,我们会采取不同的处理策略,请参照下表。

  可预测异常 不可预测异常
业务类异常
  • 在发生异常处处理
  • 将异常信息显示给用户
  • 不要记录在日志中
  • 抛出异常
  • 将异常信息显示给用户
  • 记录在日志中
技术类异常
  • 在发生异常处处理
  • 不要将异常信息显示给用户
  • 不要记录在日志中
  • 抛出异常
  • 不要将异常显示给用户
  • 记录在日志中

 

异常重构

在讲异常重构之前,我们先看下面这段代码

public void writeFile(String fileName, String data) {
	FileWriter writer = null;
	writer = new FileWriter(fileName);
	writer.write(data);
}

 这样的写法是无法通编译的,因为在FileWriter的write方法定义的时候声明了抛出IOException异常,编译器要求我们必须在调用的地方处理这个异常。

public void writeFile(String fileName, String data)  {
	FileWriter writer = null;
	try {
		writer = new FileWriter(fileName);
		writer.write(data);
	} catch (IOException e) {
		//todo
	}
}

或是在我们自定义的方法头中明确声明此异常。

public void writeFile(String fileName, String data) throws IOException {
	FileWriter writer = null;
	writer = new FileWriter(fileName);
	writer.write(data);
}

或是在调用的地方处理此异常。

 

对于第一种作法,我们并没有对异常进行作何处理,只是使用try catch语句捕获异常,并注明todo,待日后处理,但是时间一久,很容易就被遗忘了。有的小伙伴可能会说在catch语句中使用继续将该异常抛出

public void writeFile(String fileName, String data)  {
	FileWriter writer = null;
	try {
		writer = new FileWriter(fileName);
		writer.write(data);
	} catch (IOException e) {
		throw e;
	}
}

这样的做法不可取,因为这会让问题又回到了原点,在调用writeFile的函数中还是要处理我们抛出的异常呀!

 

第二种方法,和使用throw e异曲同工,同样是不处理异常,将其再次向外传递。

 

这时候就需要考虑对异常处理进行重构。我们先定义一个未处理的异常类。

/**
 * 
 * @author Chris Mao(Zibing)
 *
 */
public class UnhandledException extends Exception {
	
	private Exception exception;
	
	private String message;

	/**
	 * 
	 */
	private static final long serialVersionUID = 3490319235806360289L;
	
	public UnhandledException(Exception e, String message) {
		this.exception = e;
		this.message = message;
	}

	public Exception getException() {
		return exception;
	}

	public String getMessage() {
		return message;
	}
}

然后再将文章一开始提到的代码改为如下。

public void writeFile(String fileName, String data) throws UnhandledException  {
	FileWriter writer = null;
	try {
		writer = new FileWriter(fileName);
		writer.write(data);
	} catch (IOException e) {
		throw new UnhandledException(e, "这个异常日后再说,先让业务功能跑起来");
	}
}

这样既可以达到快速开发的要求,又可以确保日后不会忘记对这个异常的处理。

 

分享到:
评论

相关推荐

    Laboratory.zip

    Laboratory 是一个 Python 库用来处理重构关键路径。想象一下你正在实现复杂的缓存策略,那么你如何进行测试已经确保在一定压力下已经生产环境中的数据是准确无误的呢?而 Laboratory 可以:同时运行新的和老的代码...

    《构建高质量的C#代码》.(曹化宇).pdf

    第4章 处理异常 93 第5章 数组 106 第6章 结构 124 第7章 枚举 130 第8章 类 135 第9章 类的继承 170 第10章 接口 188 第11章 委托与事件 197 第12章 命名空间 207 第13章 泛型 217 第14章 运算符重载 ...

    php-tdd-exercise:PHP

    贾斯汀·约斯特(Justin Yost)涵盖编写测试双打以处理软件中的依赖性,编写基于异常的测试以及将测试用例快速添加到单元测试的核心套件中的内容。 开发人员将对测试驱动开发(TDD)周期有一个基本的了解,并了解...

    asp.net知识库

    利用委托机制处理.NET中的异常 与正则表达式相关的几个小工具 你真的了解.NET中的String吗? .NET中的方法及其调用(一) 如何判断ArrayList,Hashtable,SortedList 这类对象是否相等 帮助解决网页和JS文件中的中文...

    基于智能分布式FTU、智能分布式DTU的智能分布式馈线自动化方案实现.docx

    产品特点 广州市智昊电气技术有限公司DAF-810馈线自动化终端(分布式FTU)具有如下特点: 提高故障隔离与恢复的速度:为了保证系统的快速性,由智能FTU装置间就地动态决策,快速实现故障的自动恢复,有效减少馈线...

    igferry:一款高级的穿透网闸架构

    项目重组前,问题排查异常困难,发送消息后,业务经常不清楚是否处理了,于是整理了一下,其中以下场景: 业务希望请求可以有一定堆积,保证服务正常运行。 业务希望能够请求获得另一端网络应用实时或异步反馈。 ...

    03开源NewSql数据库TiDB-Deep Dive into TiDB

    优化 TiKV 节点空间不足时的调度策略,尽可能防止空间不足时磁盘被写满 提升 balance-leader scheduler 的调度效率 减少 balance-region scheduler 调度开销 优化 hot-region scheduler 的执行效率 4.运维接口及...

    Mybatis plus增强工具包-其他

    生成主键的多种策略 Lambda样式的API 全能和高度可定制的代码生成器 自动分页操作 SQL注入防御 支持活动记录 支持可插拔的自定义界面 内置许多有用的扩展 Mybatis-plus功能: 1、单表CURD(简单 + 批量)操作,自动...

    逆向数据分析.docx

    对网络行为判断是否为攻击行为,是否会对网络、数据造成危害的恶意行为,从而到达对网络行为进行检测和防御的目的,使用者能及时应对网络异常状况,并以最大限度的降低网络处理资源的开销,是一种侧重于风险控制的安全...

    大数据预处理技术.pdf

    ⼤数据预处理技术 学习了⽜琨⽼师的课程后整理的学习笔记,⽤于... 数量规约:⽤替代的、较⼩的数据表⽰形式替换原数据 具体⽅法包括:抽样和数据⽴⽅体聚集 数据压缩:⽆损压缩:能从压缩后的数据重构恢复原来的数据,

    UML和模式应用(架构师必备).part01.rar

    20.6 异常和错误处理 20.7 定义Sale.makeLineItem方法 20.8 实现的顺序 20.9 测试驱动或测试优先的开发 20.10 将设计映射为代码的总结 20.11 NextGen POS程序简介 20.12 Monopoly程序简介 第21章 测试驱动...

    UML和模式应用(架构师必备).part02.rar

    20.6 异常和错误处理 20.7 定义Sale.makeLineItem方法 20.8 实现的顺序 20.9 测试驱动或测试优先的开发 20.10 将设计映射为代码的总结 20.11 NextGen POS程序简介 20.12 Monopoly程序简介 第21章 测试驱动...

    UML和模式应用(架构师必备).part07.rar

    20.6 异常和错误处理 20.7 定义Sale.makeLineItem方法 20.8 实现的顺序 20.9 测试驱动或测试优先的开发 20.10 将设计映射为代码的总结 20.11 NextGen POS程序简介 20.12 Monopoly程序简介 第21章 测试驱动...

    UML和模式应用(架构师必备).part06.rar

    20.6 异常和错误处理 20.7 定义Sale.makeLineItem方法 20.8 实现的顺序 20.9 测试驱动或测试优先的开发 20.10 将设计映射为代码的总结 20.11 NextGen POS程序简介 20.12 Monopoly程序简介 第21章 测试驱动...

    UML和模式应用(架构师必备).part03.rar

    20.6 异常和错误处理 20.7 定义Sale.makeLineItem方法 20.8 实现的顺序 20.9 测试驱动或测试优先的开发 20.10 将设计映射为代码的总结 20.11 NextGen POS程序简介 20.12 Monopoly程序简介 第21章 测试驱动...

    UML和模式应用(架构师必备).part04.rar

    20.6 异常和错误处理 20.7 定义Sale.makeLineItem方法 20.8 实现的顺序 20.9 测试驱动或测试优先的开发 20.10 将设计映射为代码的总结 20.11 NextGen POS程序简介 20.12 Monopoly程序简介 第21章 测试驱动...

    UML和模式应用(架构师必备).part08.rar

    20.6 异常和错误处理 20.7 定义Sale.makeLineItem方法 20.8 实现的顺序 20.9 测试驱动或测试优先的开发 20.10 将设计映射为代码的总结 20.11 NextGen POS程序简介 20.12 Monopoly程序简介 第21章 测试驱动...

    UML和模式应用(架构师必备).part05.rar

    20.6 异常和错误处理 20.7 定义Sale.makeLineItem方法 20.8 实现的顺序 20.9 测试驱动或测试优先的开发 20.10 将设计映射为代码的总结 20.11 NextGen POS程序简介 20.12 Monopoly程序简介 第21章 测试驱动...

Global site tag (gtag.js) - Google Analytics