`
mazzystar
  • 浏览: 27336 次
  • 性别: 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);
		}

	}


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

分享到:
评论

相关推荐

    Word模板-小猪猪生活小记手信手账.docx

    根据给定文件的信息,我们可以从中提炼出与Word模板制作及使用相关的知识点,虽然原文件内容并未涉及具体的Word操作技巧或细节,但我们可以基于文件标题、描述以及可能的应用场景来展开讨论。 ### Word模板概述 ##...

    android应用登录模块访问mysql数据库小记.pdf

    在Android应用开发中,构建一个登录模块并连接到MySQL数据库是一项常见的需求,特别是在需要处理用户...对于其他开发者而言,这篇小记提供了一个实践性的参考,帮助他们避免遇到类似的问题,顺利地构建自己的登录模块。

    大方法的执行性能与调优过程小记1

    在Java编程中,大型方法(即超过2500行的方法)并不常见,通常是通过自动化工具生成,如模板编译或语言转换。然而,这样的大方法在Hotspot JVM上可能会遇到性能问题。从描述中我们可以看到,一个名为`play()`的方法...

    vuex使用方法,小记总结

    Vuex 使用方法总结 Vuex 是一个专门为 Vue.js 设计的状态管理器,用于管理应用程序的状态。下面是 Vuex 的使用方法总结: State Vuex 的状态管理是通过 State 来实现的。State 是一个对象,存储了应用程序的所有...

    java小记.rar

    Servlet通过继承HttpServlet类并覆盖doGet或doPost等方法来实现动态网页的生成。例如,你可以看到作者可能记录了如何处理HTTP请求、响应头和体的设置,以及如何使用Servlet进行会话管理。 JSP(Java Server Pages)...

    android开发小记

    在“android开发小记”这个主题中,我们可以深入探讨Android应用程序开发的相关知识,特别是通过查看提供的压缩文件中的代码示例。这些文件名如lesson_8_code.zip至lesson_20_codel.zip,以及不同的Mp3Player版本,...

    物业公司消防演练小记模板.docx

    4. **紧急疏散与逃生演练**:模拟火灾发生时的疏散过程,让员工熟悉逃生路线和方法,提高逃生效率,降低伤亡风险。同时,进行现场急救演练,提升员工在火灾现场进行初级救助的能力。 5. **单甩水带消防灭火演练**:...

    每日小记,记录账单和日记

    "每日小记"就是这样一款应用,它结合了记账和日记的功能,为用户提供了一个全面的生活记录平台。 首先,我们要了解记账的重要性。在个人财务管理中,记账是一个基础但至关重要的步骤。通过"每日小记",用户可以轻松...

    C++编程小记,经典收藏

    - **注意事项**:如果派生类的方法名称与基类的虚方法不同,则编译器将报错。 - **`final`关键字**: - 用于标记虚函数或整个类不可被进一步覆盖或继承。 - **示例**: ```cpp class E { public: virtual ...

    数据结构习题总结 拾荒小记

    2. **模式匹配**:这是一个在字符串中寻找特定子串的问题,常见的算法有KMP(Knuth-Morris-Pratt)算法和Boyer-Moore算法,它们在文本搜索和文本处理中非常实用。 3. **矩阵**:矩阵是二维数组,常见的操作有矩阵...

    asp.net Jmail使用小记

    "Jmail组件使用小记.doc"文件很可能包含了更详尽的使用教程和注意事项,包括如何处理错误、如何调试、如何设置HTML格式的邮件、如何使用模板等功能。阅读这份文档可以帮助你更深入地理解和使用Jmail组件,解决在实际...

    Linux boost库安装、编译问题小记

    环境: Linux s12084 2.6.9-67.ELsmp #1 SMP Wed ...小记一下。以备以后参考。  boost 库做得真好。在windows 平台, linux 平台下编译都很顺利。hp aCC 也宣称对 boost 1.35 完全支持 。  全部编译是很痛苦的过程

    随笔小记.doc

    随笔小记.doc

    安卓做的小记账本app.zip

    2. **报告**:可能包括`project_report.txt`或`design_document.pdf`等,详细阐述了应用的功能规划、设计决策、实现方法和测试结果。 3. **PPT**:可能名为`presentation.pptx`,展示了应用的概览、用户界面截图、...

    GeoStudio学习小记.pdf

    GeoStudio学习小记

    python进行爬虫小记

    Python爬虫技术是一种用于自动化网页数据抓取的编程方法,尤其适合初学者快速入门。Python在爬虫领域具有显著优势,因为其拥有丰富的第三方库,如requests、lxml和parsel等,使得编写爬虫代码变得简洁高效。此外,...

    CGContext 小记

    这篇小记将深入探讨CGContext的相关知识点,包括它的基本概念、使用方法以及在实际开发中的应用。 首先,CGContext是Core Graphics框架中的图形上下文,它负责管理图形绘制的目标,如屏幕、图片、PDF文档等。通过...

    TCP-IP小记

    1. 应用层:这是最顶层,直接与用户应用程序交互。常见的应用层协议有HTTP(超文本传输协议)用于浏览网页,FTP(文件传输协议)用于文件传输,SMTP(简单邮件传输协议)用于电子邮件服务,以及DNS(域名系统)用于...

    Flex整合J2EE开发小记+源码下载

    标题中的“Flex整合J2EE开发小记+源码下载”揭示了本次讨论的主题,即如何将Adobe Flex技术与Java企业版(J2EE)框架相结合进行应用开发,并且提供了相关的源代码供学习和参考。Flex是一种用于构建富互联网应用程序...

Global site tag (gtag.js) - Google Analytics