欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

异常处理策略与重构

程序员文章站 2022-06-07 11:33:33
...

异常处理策略

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

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

 

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

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

 

异常重构

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

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, "这个异常日后再说,先让业务功能跑起来");
	}
}

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