模板方法:抽取通用的流程(执行逻辑),定义抽象方法,通过定义多个子类以获取不同的实现。
原来的代码:
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);
}
}
代码不见得比原来少,但是心情却舒畅了,符合开心工作的原则。
分享到:
相关推荐
Word模板-小猪猪生活小记手信手账.docx
vuex使用方法,小记总结
物业公司消防演练小记模板.docx
android应用登录模块访问mysql数据库小记.pdf
【咬人草小记,阅读附答案】 咬人草小记阅读答案.docx
流程图与控制流图课堂小记.流程图与控制流图课堂小记.流程图与控制流图课堂小记.流程图与控制流图课堂小记.流程图与控制流图课堂小记.流程图与控制流图课堂小记.流程图与控制流图课堂小记.流程图与控制流图课堂小记....
TCP-IP小记
很全面的,很实用的,看完提高不少,不管新手老手,都绝对有用
随笔小记.doc
python进行爬虫小记,主要用于python快速入门理解。
c语言理论知识小记
GeoStudio学习小记
海居小记
环境: Linux s12084 2.6.9-67.ELsmp #1 SMP Wed ...小记一下。以备以后参考。 boost 库做得真好。在windows 平台, linux 平台下编译都很顺利。hp aCC 也宣称对 boost 1.35 完全支持 。 全部编译是很痛苦的过程
我做java web 多年的小记,希望能打大家有用
asp.net Jmail组件使用小记
NULL 博文链接:https://zfwdl2005.iteye.com/blog/1308748
redis安全学习小记1
本草缘·种植小记