`
zhaonjtu
  • 浏览: 129760 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

由一段代码引起的

阅读更多

  最先接触hibernate关于业务的操作都是通过session操作的,好长时间没有用,再去看代码的时候发现一些看不懂的地方。先看看代码 

        return (List) this.getHibernateTemplate().execute(
                new HibernateCallback()
                {
                    public Object doInHibernate(Session session)
                            throws HibernateException, SQLException
                    {
                        Query query = null;
                        query = session
                                .createQuery("from TsMoniSession session where 1=1");
                        return query.list();
                    }
                });

 

项目中的代码大量的充斥着这种写法,每一个操作都是通过callback去调用hibernate的方法,这个callback到底是个什么原理,但是明明template明明也提供了更为简单的find方法,为什么不去用呢?先去理解理解callback吧。

    如果是一个初学者,在碰到下面一个问题的情况下会采取什么样的解决方法。

    问题:boss要他计算一下程序中的10个方法的计算时间成本,记录到日志中去。

    方案1:这还不简单,每个方法前面加上开始时间,结尾加上结束时间,然后取差就

     可以了。代码如下:

    

  long before=System.currentTimeMillis(); 
  method1(); 
  long after=System.currentTimeMillis(); 
  log.info("the cost is:"+(after-before));

 

 

 

  非常对,这个解决办法很好的达到目的。但是问题出来了,如果是有1000个这样的方法,工作量就很大了。而且即使十个方法而言,代码本身就有大量重复的代码,这就意味着有可以改进的地方。想象一下:我们(开发者)在使用method的时候都是直接去调用,如果在这个中间可以加一层,然后这个层是对方法可以包装的话,是不是就可以减少那么多重复的代码量呢。我们暂时把它叫做TemplateMethod吧. 那怎么设计呢?难不成我们调用method的时候把方法名作为参数传进去。

方案二:

public void doMethod(String methodName, Object[] parameters)
	{
		long before = System.currentTimeMillis();
		利用java反射执行method
		long after = System.currentTimeMillis();
		log.info("the cost is:"+(after-before));
	}

 

   虽然很好的解决了代码量重复的问题,但是怎么看怎么别扭,因为他完全改变了使用者原先调用方法的习惯,为了计算成本不得不换成后来的调用方式,实在是一种不太优雅的设计。

  接口,接口,设计模式这些都是设计优雅的程序的基本,来看看一个即不改变原先调用习惯,又能节省代码的设计。

   CallBack.java 

public interface CallBack
{
    public void doInMyMethod();
}

  

  TemplateMethod.java

public class TemplateMethod
{
	public void computeCost(CallBack callback)
	{
		long before = System.currentTimeMillis();
		callback.doInMyMethod("");
		long after = System.currentTimeMillis();
		log.info("the cost is:" + (after - before));
	}
}

  

   再看看我们都怎么使用templateMethod去调用我们的方法

 

 如此的调用方式基本上已经达到了目的了,是不是很熟悉,和本文开头的hibernate的回调很像,没错,spring的设计正是想让使用者还是能像以前使用session操作一样去操作hibernate,不同的是hibernate template已经帮我们做好一些其他的事情了,比如session的获取,session的flush等等。不仅仅是hibernate,ibatis都是有这样的template。到这里我们总算清楚了callback的一点内幕了,再看看为什么使用者为什么用这种方式而不用template的find方法,根据我的理解

  1.   习惯问题,习惯了seesion的使用方式
  2.    如果一个业务操作既要查询,又要修改,删除的,如果用template的方法的话,效率显然要低点(如果看看hibernateTemplate的源代码的话,template的方法也是通过回调调用hibernate的方法,只不过包装的更好了),所以干脆就用回调使用hibernate了

回到那个计算时间成本的例子,当然最好的方法是通过spring的aop了,这就是框架的方便之处。

 

 

 

 

 

 

分享到:
评论

相关推荐

    一段“平淡无奇”代码引起的反思

    有时候盯着一段“平淡无奇”的代码进行细细品味时,是不是都会有一种错觉:“哪里感觉好像有问题,可一时又说不上来”。这个时候,请为自己画地为牢,用内心的好奇禁锢住离开的脚步,驻足一下,开启探坑模式。当自己...

    一段Spring代码引起的调用绑定总结

    NULL 博文链接:https://jinnianshilongnian.iteye.com/blog/2025189

    java代码规范

    我们可以先想像没有统一风格的情况下,A完成开发以后,B进行维护加一段代码,过一段时间C又加一段代码。。。。。。直到有一天X看到那一大堆乱码想死的心都有了,维护也就进行不下去了。因此,统一的风格有利于长期的...

    MATLAB代码,用笔记本摄像头输入的一段人脸视频进行自动心率估计,简单可靠,精度高

    MATLAB代码,用笔记本摄像头输入的一段人脸视频进行自动心率估计,主要原理是人类血液对与各种频率的光照都有一定的吸收作用,而心跳会引起皮下的毛细血管血液流量变化,从而使皮肤的颜色在心跳的作用下进行周期性的...

    matlab不运行一段代码-Career-Fair-Directory:职业公平目录

    matlab不运行一段代码职业公平目录 名为Tool_guide.docx的文件包含这些相同的指令以及图像。 前言 该目录长期以来是职业博览会的主要内容。 样本可追溯到90年代中期,显示了自那时以来目录的发展。 随着公司数量的...

    dltmatlab代码-Flash-Reflection-Image-Treatment:在这个小代码中,我通过将同一物体从不同角度拍摄的4张

    dlt matlab代码闪光反射图像处理 在这个小代码中,我通过将同一...可以看到MatLab代码分为2段,上一段是手动选点,下一段是自动选点。 输入: 输出(使用手动点选择): 输出(使用detectSURFFeatures,自动点选择):

    自己动手写操作系统(含源代码).part2

    而假如你真的因为我的书而重新燃起实践的热情,从而开始一段操作系统旅程,我将会感到非常高兴。 不过我得坦白,在写作《自己动手写操作系统》的时候,我并不敢期待它能引起多少反响,一方面因为操作系统并不是时尚...

    自己动手写操作系统(含源代码).part1

    而假如你真的因为我的书而重新燃起实践的热情,从而开始一段操作系统旅程,我将会感到非常高兴。 不过我得坦白,在写作《自己动手写操作系统》的时候,我并不敢期待它能引起多少反响,一方面因为操作系统并不是时尚...

    cpp-stub 开源代码

    这是一个单元测试打桩开源代码,在git上下载的代码在ARM平台上有一个BUG,使用stub.h中的reset方法时,会引起段错误,该资源对这个bug进行了修复。

    多功能.NET代码自动生成器(含存储过程)

    易于扩展,避免项目开发过程中数据库结构调整所引起大量的基础类库代码维护工作,避免多个人维护同一个类时引起代码紊乱。 2、扩展存储过程说明 步骤如下: 1) 在数据库中新建存储过程; 2) 在DAL文件夹下新建分布类...

    JS 分号引起的一段调试问题

    来看一下下面的代码: var a=textbox1.text; var b=5; if(a<b);//如果用户输入的值小于5,就取5 { a...一不小心犯的错,却花了不少时间来解决. 注:刚写下的经过,再次打开时,没有内容了.因此就精简一点了.写个大致意思了

    c51智能卡cos操作系统源代码-keil uv2

    但是由于目前智能卡的发展速度很快,而国际标准的制定周期相对比较长一些,因而造成了当前的智能卡国际标准还不太完善的情况,据此,许多厂家又各自都对自己开发的COS作了一引起扩充。  就目前而言,还没有任何...

    windows系统蓝屏代码(全)

    系统蓝屏70%是由于内存(病毒)引起的 一般来说 你先系统重新装一遍 要是用了一段时间还是出现这样的问题。

    ICD-10与SNOMED实验

    假设某医院的医生书写病历的习惯如下,编写一段程序,将以下一段话的诊断结论提取出来并转变为ICD10的编码,并利用数据库里SNOMED的D,G,C数据表来表达该诊断的意思,界面如下: 2009/4/1,张三染发后头皮红疹,发痒...

    matlab电磁波代码-LSM-electromagnetic:LSM-电磁

    这段代码是我博士项目的一部分。 目的是基于电磁远场数据,测试用于识别分层介质中的薄缺陷(分层)的数值算法。 数值算法的开发采用定性逆散射技术(线性采样方法)来解决我们的问题。 该算法基于严重不适定线性...

    net学习笔记及其他代码应用

    29.根据线程安全的相关知识,分析以下代码,当调用test方法时i>10时是否会引起死锁?并简要说明理由。 public void test(int i) { lock(this) { if (i>10) { i--; test(i); } } } 答:不会发生死锁,(但...

    深度学习笔记(5):第一课第二周的作业题第一部分详解与代码

    注意两点 1)记住shift+Entershift+Entershift+Enter快捷键 2)记住要从import那一段代码开始一直运行到你需要的部分,否则可能会因为中断而引起代码错误 手写一个简单的sigmoid函数 很简单,我们只需要知道对于单个...

    Python出现segfault错误解决方法

    最近python程序在运行过程中偶尔会引发系统segfault的错误,而且是在不定期不同代码段时发生的,所以单步调试没办法确定是哪一行代码的问题。 段错误, 这个现象太离奇了。在系统日志里message中一开始提示为python...

    c c++ 编程规范

    接口错误及由于代码可理解度低导致优化维护阶段对代码的错误修改引起的错误则占了一半 以上 可见提高软件质量必须降低编码阶段的错误率如何有效降低编码阶段的错误呢BELL实 验室的研究人员制定了详细的软件编程...

    对非教条软件开发的调查。 一项实验表明,与等效的本机 C 代码相比,在 JVM 上运行的代码具有双倍的性能。

    ”“嗯,让我试试,这里有一段 Java 代码,直接等价于 C 语言,第一个几乎快了 2 倍。”“那是因为你做错了。没有人会写这样的 C 代码。”“为什么?”“因为你需要正确管理你的记忆以提高效率。”“你怎么做呢?”...

Global site tag (gtag.js) - Google Analytics