论坛首页 Java企业应用论坛

实践中的重构09_多余的防御性编程(new)

浏览 1781 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-12-04   最后修改:2011-06-06
众所周知,防御性编程是一个编程的最佳实践。良好的防御性编程,可以增强程序的健壮性,但是没有银弹,最佳实践也有一个适用场景的问题。
试看如下代码:
	/**
	 * 异常处理接口。
	 * */
	public interface ExceptionHandler {

		/**
		 * 是否处理该异常。
		 * */
		public boolean aboutToHandle(Exception ex);

		/**
		 * 处理异常。
		 * */
		public void handle(Exception ex);
	}

	/**
	 * 默认异常处理器。
	 * */
	public class DefaultExceptionHandler implements ExceptionHandler {

		// get exceptionHandlerList from config file or somewhere.
		private List<ExceptionHandler> exceptionHandlerList;

		@Override
		public boolean aboutToHandle(Exception ex) {
			return true;
		}

		@Override
		public void handle(Exception ex) {
			for (ExceptionHandler exceptionHandler : exceptionHandlerList) {
				if (exceptionHandler.aboutToHandle(ex)) {
					exceptionHandler.handle(ex);
					return;
				}
			}
		}
	}

	/**
	 * 空指针异常处理器。
	 * */
	public class NullPointerExceptionHandler_0 implements ExceptionHandler {

		@Override
		public boolean aboutToHandle(Exception ex) {

			if (ex instanceof NullPointerException) {
				return true;
			}

			return false;
		}

		@Override
		public void handle(Exception ex) {

			NullPointerException exception = null;

			if (ex instanceof NullPointerException) {
				exception = (NullPointerException) ex;
			}

			if (exception == null) {
				return;
			}

			// 其他处理
		}
	}

这段代码是一段很通用的异常处理代码,接口的定义很简洁,aboutToHandle方法来确定是否由该异常处理器来处理该异常,handle方法是实际的异常处理方法。DefaultExceptionHandler这个异常处理器实际上起着一个分发异常的作用,是这个异常处理机制的核心。
初看这段代码,会认为这段代码和大多数的异常处理机制大同小异,没有什么问题。细致的检查之后,这段代码还是有它的缺点的。
1 NullPointerExceptionHandler的aboutToHandle方法体不够简洁。
2 NullPointerExceptionHandler的handle方法中用了防御性编程,在该特定场景中防御性代码是冗余的。
一般而言,异常处理系统是作为基础子系统存在的,不应该被外界的代码随意调用。因此,异常处理的具体实现应该信任作为该系统中的核心类(该处为DefaultExceptionHandler)的功能。即分发给一个处理器的异常,一定是可以通过该处理器aboutToHandle方法测试通过的,如果该条件不满足,aboutToHandle方法的存在本身也就没有意义了。该方法本身就是对异常处理器可以处理哪些异常的一个抽象。
基于以上理解,代码修改如下:
	/**
	 * 重构后的空指针异常处理器。
	 * */
	public class NullPointerExceptionHandler_1 implements ExceptionHandler {

		@Override
		public boolean aboutToHandle(Exception ex) {

			return (ex instanceof NullPointerException);

		}

		@Override
		public void handle(Exception ex) {

			NullPointerException exception = (NullPointerException) ex;

			// 其他处理
		}
	}

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics