从Spring HibernateTemplate模板方法设计模式的实现谈起
概述
模板方法模式是GOF设计模式中很典型的设计模式,其意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用。Spring模板方法模式实际是模板方法模式和回调模式的结合,Spring几乎所有的外接扩展都采用这种模式,如JNDI,JMS,JCA的 CCI,JDBC,ORM中的Hiberate3、jdo、Toplink等扩展都采用模板方法模式来扩展。
经典的模板方法设计模式
开闭原则是指一个软件实体应该对扩展开放,对修改关闭。先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。如图所示,面向接口编程,client只需调用Template接口中的execute方法,在AbstractTemplate抽象类的示例代码所示,实现execute()方法,但在execute()方法中制定所需的大的步骤,调用如subExecute1(),subExecute2(),subExecute3()方法来完成,但AbstractTemplate抽象类把subExecute1(),subExecute2()设置为抽象方法,由子类来实现,subExecute3()给出了缺省实现,也可由子类来覆盖,如SubTemplateImpl2类。
|
public abstract class AbstractTemplate implements TemplateInterface { public void execute() { subExecute1(); subExecute2(); subExecute3(); } protected abstract void subExecute1(); protected abstract void subExecute2(); protected void subExecute3() { } } |
-- HibernateTemplate提供的便利
-- 一般我们使用Session的时候,如果这个Session是通过SessoionFactory的openSession方法而来,那么我们需要通过Try-Catch-Finally代码块来讲Session以及Transaction操作包裹。这么做的目的主要有两方面:
1. 出现异常时及时回滚Transaction。
2. 无论出现异常与否都可以在Finally代码块里关闭Session。这种情况就如同使用JDBC通过Connection连接数据库的操作。
-- 但是在Hibernate中,Session有关数据库操作的方法很多,如果在每次使用这些Session方法时都写一遍Try-Catch-Finally代码块,我们的代码就会变得很不优雅。不符合面向对象复用的原则。
-- 使用HibernateTemplate(实际上Spring对包括JDBC在内的大部分持久化技术都做了Template的支持),也就是模板方法设计模式,就可以免去重复这些代码块的工作。而只需要集中于Session的方法调用就可以了。
-- HibernateTemplate的使用
-- 将HibernateTemplate交给Spring管理
-- 将HibernateTemplate实例注入程序
-- 调用HibernateTemplate执行Session方法
-- HibernateTemplate实现模板方法设计模式的原理
-- 从HibernateTemplate的save开始
-- 按照执行步骤查看executeWithNativeSession方法
-- doExecute方法
-- 下图中用黄色底色条标出的就是我们的匿名内部类对象。
-- doExecute方法回调了该对象的doInHibernate方法
-- 这里解释一下回调函数
-- 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
-- 但是在Java中并没有指针这种东西,所以使用了通过匿名内部类传递回调函数的办法。
-- 为什么要使用回调函数
因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。简而言之,回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。
-- Java中使用回调函数的例子
在Java的listener模型中,一个事件发生,那么系统就会调用通过匿名内部类实现的handler,来做出响应。
-- 关于为什么匿名内部类使用方法的局部变量时,该变量需要声明为final的解释
-- 其实解释总结起来就是局部变量的生命周期太短,没有匿名内部类对象的生存周期长。所以必须将局部变量声明为final。从而该变量就不会被放在JVM存储区域的栈中,而会被放在方法区中,从而延长了生命周期,
-- The difference is between local (method) variables vs class member variables. A member variable exists during the lifetime of the enclosing object, so it can be referenced by the inner class instance. A local variable, however, exists only during the method invocation, and is handled differently by the compiler, in that an implicit copy of it is generated as the member of the inner class. Without declaring the local variable final, one could change it, leading to subtle errors due to the inner class still referring to the original value of that variable.
从Spring HibernateTemplate模板方法设计模式的实现谈起的更多相关文章
- Spring 事务模板方法设计模式
接上一篇文章 上一篇讲到了doGetTransaction方法 一.模板方法设计模式 这里涉及到了一个经典的设计模式:模板方法 如下图: AbstractPlatformTransactionMana ...
- 五、模板方法设计模式及在Spring中的应用
模板方法模式是一种行为型设计模式,具体定义网络上很多资源搜到本文不赘述. 如果字面理解比较抽象的话,那以生活中简单的行为为例:天热了,到了晚上妈妈都要将今天没有吃完的饭菜放入冰箱.将饭菜放入冰箱就是一 ...
- Spring中的设计模式
[Spring中的设计模式] http://www.uml.org.cn/j2ee/201301074.asp [详解设计模式在Spring中的应用] [http://www.geek521.c ...
- JDK和Spring中的设计模式
创建型 1)工厂方法 Collection.iterator() 由具体的聚集类来确定使用哪一个Iterator 2)单例模式 Runtime.getRuntime() 3)建造者模式 StringB ...
- 大话设计模式-->模板方法设计模式
在学习java的过程中,我们肯定听到过设计模式这名词,在行业中有这么一句话,若您能熟练的掌握23种设计模式,那么你便是大牛! 好了,废话不多说,今天我跟大家分享一下23种设计模式之一的 模板方法 设 ...
- Java抽象类深入理解-----模板方法设计模式(Templete Method)
模板方法设计模式(Templete Method) 定义一个操作中的算法骨架,而将一些可变部分的实现延迟到子类中. 模板方法设计模式使得子类可以不改变一个算法的结构即可重新定义该算法某些特定的步骤. ...
- Spring HibernateTemplate的使用
Spring HibernateTemplate的使用 2008-03-25 11:38 2020人阅读 评论(0) 收藏 举报 springbeanhibernatesessiondaoclass ...
- 【设计模式】【应用】使用模板方法设计模式、策略模式 处理DAO中的增删改查
原文:使用模板方法设计模式.策略模式 处理DAO中的增删改查 关于模板模式和策略模式参考前面的文章. 分析 在dao中,我们经常要做增删改查操作,如果每个对每个业务对象的操作都写一遍,代码量非常庞大. ...
- Java设计模式——模板方法设计模式(abstract修饰)
解释: 一个抽象类中,有一个主方法,再定义 1...n 个方法,可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用. 解决的问题: 当功能内部一 ...
随机推荐
- Android_Chronometer计时器
最近做一个项目用到Handler 和Message ,开始时不是很明白,不了解其中的内部机制,所以开发起来有点难度,之后自己找了Android 时间服务 这一节的内容,总结了一点关于时间的知识,在这里 ...
- SSH+Ajax实现用户名重复检查(二)
1.另外一种更常用的js表达方式: var user = { inintEvent: function(){ $("input[name='user.User_LogName']" ...
- parseInt()、parseFloat()与Number()的比较
我有一个同学最近在自学JavaScript,偶尔遇到问题了会让我帮忙解决,虽然我也是一个JavaScript菜鸟,但是我还是很乐意帮忙,这样不仅可以帮到别人,也可以让自己在解决问题的过程中学到更多知识 ...
- validate中remote的用法
jquery中的插件validate主要可以用于表单验证,极大地方便了我们,而validate中的remote方法更是非常的方便.以下介绍它的两个主要用途 1.注册时用于验证用户名是否存在 >& ...
- bootstrap table 行号 显示行号 添加行号 bootstrap-table 行号
思想:借助bootstrap-table 本身的index属性, 巧妙的的通过formatter 实现 { field: 'Number', title: 'Number', formatter: f ...
- TP框架多上传域上传图片
问题: 学习使用TP框架做电商网站是,添加商品表单需要上传商品logo和商品图片pics,有两个上传域,第一个上传域是logo,只上传一张,第二个上传域是pics,上传多张图片.使用如下代码,总是报错 ...
- Cakephp 创建无模型的Controller
控制器(Controller)如果没有特定的表/模型关联的话,哪怕建测试都会出错,但你可以加一行到控制器(Controller)里就好了public $uses=array(); 或者 public ...
- php结合jquery异步上传图片(ajaxSubmit)
php结合jquery异步上传图片(ajaxSubmit),以下为提交页面代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transi ...
- 更新 requests 包之后报 has no attribute '__getitem__' 的错
翻代码的时候看到段一年多前用 python 写的下载图片站图片的代码. 测试下看还能不能下到图片,结果发现跑不起来了,报了个如下的错误: TypeError: 'instancemethod' obj ...
- JAVA技术体系发展路线
JAVA技术体系 1.1 Java程序员 ·高级特性 反射.泛型.注释符.自动装箱和拆箱.枚举类.可变参数.可变返回类型.增强循环.静态导入 ·核心编程 IO.多线程.实体类.集合类.正则表达式.XM ...