`
mazzystar
  • 浏览: 26454 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

模板方法模式应用小记

阅读更多
模板方法:抽取通用的流程(执行逻辑),定义抽象方法,通过定义多个子类以获取不同的实现。

原来的代码:
public void intercept(InterceptorChain chain) throws Throwable {
		boolean con = true;
		if(Context.isMe(chain, this)) {
			con = beforeInvoke(chain.getTarget(), chain.getMethod(), chain.getArgs());
			Context.meFinished();
		} else if(allowNesting) {
			log("allow", "before", chain);
			con = beforeInvoke(chain.getTarget(), chain.getMethod(), chain.getArgs());
		} else {
			log("prevent", "before", chain);
		}
			
		long s = System.nanoTime();
		try {
			if (con) {
				chain.doChain();
			}
		} catch (Exception e) {
			boolean throwEx = true;
			
			if(Context.isMe(chain, this)) {
				throwEx = whenInvokeException(e, chain.getTarget(), chain.getMethod(), chain.getArgs());
				Context.meFinished();
			} else if(allowNesting) {
				log("allow", "after", chain);
				throwEx = whenInvokeException(e, chain.getTarget(), chain.getMethod(), chain.getArgs());
			} else {
				log("prevent", "after", chain);
			}
			
			if (throwEx) {
				throw e;
			}
		} finally {
			if(Context.isMe(chain, this)) {
				Object obj = afterInvoke(s,chain.getReturnValue(),chain.getTarget(),chain.getMethod(),chain.getArgs());
				chain.setReturnValue(obj);
				Context.meFinished();
			} else if(allowNesting) {
				log("allow", "after", chain);
				Object obj = afterInvoke(s,chain.getReturnValue(),chain.getTarget(),chain.getMethod(),chain.getArgs());
				chain.setReturnValue(obj);
			} else {
				log("prevent", "after", chain);
			}
		}
		
	}

可以看出这一段重复了3次
if(Context.isMe(chain, this)) {
    ...
} else if(allowNesting) {
    ...
} else {
    ...
}

当我写到第三次时已经抓狂了,这已经不是多几行代码少几行代码的事了,我怕以后有人维护这段代码时会默默诅咒我。

于是套用模板方法,修改如下:

// 定义模板
private static abstract class Template {
		String type;
		
		public Template(String type) {
			super();
			this.type = type;
		}

		boolean intercept(InterceptorChain chain, AbstractInterceptor i,
Exception e,long beginTime) {
			boolean r = true;
			if (Context.isMe(chain, i)) {
				r = doIntercept(chain, i,e,beginTime);
				Context.meFinished();
			} else if (i.allowNesting) {
				i.log("allow", type, chain);
				r = doIntercept(chain, i,e,beginTime);
			} else {
				i.log("prevent", type, chain);
			}
			return r;
		}

		abstract boolean doIntercept(InterceptorChain chain,
				AbstractInterceptor i,Exception e,long beginTime);
	}
	
        // 定义3个不同的实现。

	private static final Template before = new Template("before") {
		boolean doIntercept(InterceptorChain chain, AbstractInterceptor i,
Exception e,long beginTime) {
			return i.beforeInvoke(chain.getTarget(), chain.getMethod(), chain.getArgs());
		}
	};
	
	private static final Template after = new Template("after") {
		boolean doIntercept(InterceptorChain chain, AbstractInterceptor i,
Exception e,long beginTime) {
			Object obj = i.afterInvoke(beginTime,chain.getReturnValue(),chain.getTarget(),chain.getMethod(),chain.getArgs());
			chain.setReturnValue(obj);
			return true;
		}
	};
	
	private static final Template whenException = new Template("whenException") {
		boolean doIntercept(InterceptorChain chain, AbstractInterceptor i,
Exception e,long beginTime) {
			 return i. whenInvokeException(e, chain.getTarget(), chain.getMethod(), chain.getArgs());
		}
	};
	
	// 这是之前的那个方法
	public void intercept(InterceptorChain chain) throws Throwable {
		boolean doChain = before.intercept(chain, this, null, 0L);

		long s = System.nanoTime();
		
		try {
			if (doChain) {
				chain.doChain();
			}
		} catch (Exception e) {
			if (whenException.intercept(chain, this, e, s)) {
				throw e;
			}
		} finally {
			after.intercept(chain, this, null, s);
		}

	}


代码不见得比原来少,但是心情却舒畅了,符合开心工作的原则。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics