模板方法:抽取通用的流程(执行逻辑),定义抽象方法,通过定义多个子类以获取不同的实现。
原来的代码:
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模板制作及使用相关的知识点,虽然原文件内容并未涉及具体的Word操作技巧或细节,但我们可以基于文件标题、描述以及可能的应用场景来展开讨论。 ### Word模板概述 ##...
在Android应用开发中,构建一个登录模块并连接到MySQL数据库是一项常见的需求,特别是在需要处理用户...对于其他开发者而言,这篇小记提供了一个实践性的参考,帮助他们避免遇到类似的问题,顺利地构建自己的登录模块。
在Java编程中,大型方法(即超过2500行的方法)并不常见,通常是通过自动化工具生成,如模板编译或语言转换。然而,这样的大方法在Hotspot JVM上可能会遇到性能问题。从描述中我们可以看到,一个名为`play()`的方法...
Vuex 使用方法总结 Vuex 是一个专门为 Vue.js 设计的状态管理器,用于管理应用程序的状态。下面是 Vuex 的使用方法总结: State Vuex 的状态管理是通过 State 来实现的。State 是一个对象,存储了应用程序的所有...
Servlet通过继承HttpServlet类并覆盖doGet或doPost等方法来实现动态网页的生成。例如,你可以看到作者可能记录了如何处理HTTP请求、响应头和体的设置,以及如何使用Servlet进行会话管理。 JSP(Java Server Pages)...
在“android开发小记”这个主题中,我们可以深入探讨Android应用程序开发的相关知识,特别是通过查看提供的压缩文件中的代码示例。这些文件名如lesson_8_code.zip至lesson_20_codel.zip,以及不同的Mp3Player版本,...
4. **紧急疏散与逃生演练**:模拟火灾发生时的疏散过程,让员工熟悉逃生路线和方法,提高逃生效率,降低伤亡风险。同时,进行现场急救演练,提升员工在火灾现场进行初级救助的能力。 5. **单甩水带消防灭火演练**:...
"每日小记"就是这样一款应用,它结合了记账和日记的功能,为用户提供了一个全面的生活记录平台。 首先,我们要了解记账的重要性。在个人财务管理中,记账是一个基础但至关重要的步骤。通过"每日小记",用户可以轻松...
- **注意事项**:如果派生类的方法名称与基类的虚方法不同,则编译器将报错。 - **`final`关键字**: - 用于标记虚函数或整个类不可被进一步覆盖或继承。 - **示例**: ```cpp class E { public: virtual ...
2. **模式匹配**:这是一个在字符串中寻找特定子串的问题,常见的算法有KMP(Knuth-Morris-Pratt)算法和Boyer-Moore算法,它们在文本搜索和文本处理中非常实用。 3. **矩阵**:矩阵是二维数组,常见的操作有矩阵...
"Jmail组件使用小记.doc"文件很可能包含了更详尽的使用教程和注意事项,包括如何处理错误、如何调试、如何设置HTML格式的邮件、如何使用模板等功能。阅读这份文档可以帮助你更深入地理解和使用Jmail组件,解决在实际...
环境: Linux s12084 2.6.9-67.ELsmp #1 SMP Wed ...小记一下。以备以后参考。 boost 库做得真好。在windows 平台, linux 平台下编译都很顺利。hp aCC 也宣称对 boost 1.35 完全支持 。 全部编译是很痛苦的过程
随笔小记.doc
2. **报告**:可能包括`project_report.txt`或`design_document.pdf`等,详细阐述了应用的功能规划、设计决策、实现方法和测试结果。 3. **PPT**:可能名为`presentation.pptx`,展示了应用的概览、用户界面截图、...
GeoStudio学习小记
Python爬虫技术是一种用于自动化网页数据抓取的编程方法,尤其适合初学者快速入门。Python在爬虫领域具有显著优势,因为其拥有丰富的第三方库,如requests、lxml和parsel等,使得编写爬虫代码变得简洁高效。此外,...
这篇小记将深入探讨CGContext的相关知识点,包括它的基本概念、使用方法以及在实际开发中的应用。 首先,CGContext是Core Graphics框架中的图形上下文,它负责管理图形绘制的目标,如屏幕、图片、PDF文档等。通过...
1. 应用层:这是最顶层,直接与用户应用程序交互。常见的应用层协议有HTTP(超文本传输协议)用于浏览网页,FTP(文件传输协议)用于文件传输,SMTP(简单邮件传输协议)用于电子邮件服务,以及DNS(域名系统)用于...
标题中的“Flex整合J2EE开发小记+源码下载”揭示了本次讨论的主题,即如何将Adobe Flex技术与Java企业版(J2EE)框架相结合进行应用开发,并且提供了相关的源代码供学习和参考。Flex是一种用于构建富互联网应用程序...