异常处理策略与重构

异常处理策略

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

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

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

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

异常重构

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

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

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

猜你喜欢

转载自cmao.iteye.com/blog/2249766
今日推荐