逝去的青春

勇往直前

2006年2月28日 #

回调函数在Spring中的使用

   这是一种对单个方法的参数使用控制反转,把控制权和差错处理交给框架来处理。严格的说,这是一种Strategy模式的特例,他们的区别就在于接口的复杂度不同。
   在Spring的JdbcTemplate中就使用了这种模式。JdbcTemplate实现了query()方法,参数是SQL字符串,和一个实现了回调接口的,将在读取resultSet每行时被调用。

1 public   interface  RowCallbackHandler 
2 {
3      void  processRow(ResultSet rs)  throws  SQLException;
4 }
 


  query()方法封装了对JDBC底层API的调用。

public   void  query(String sql, RowCallbackHandler callbackHandler)  throws  JdbcSqlException 
{
    Connection con 
=   null ;
    PreparedStatement ps 
=   null ;
    ResultSet rs 
=   null ;
    
try  
    
{
        con 
=   < code to get connection >
        ps 
=  con.prepareStatement (sql);
        rs 
=  ps.executeQuery();
        
while  (rs.next()) 
        
{
            callbackHandler.processRow(rs);
        }

        rs.close();
        ps.close();
    }
 
    
catch  (SQLException ex) 
    
{
        
throw   new  JdbcSqlException( " Couldn't run query [ "   +  sql  +   " ] " , ex);
    }

    
finally  
    
{
        DataSourceUtils.closeConnectionIfNecessary(
this .dataSource, con);
    }

}


   在上面的例子中,JdbcSqlException继承了java.lang.RuntimeException,也就是说调用者可以选择去捕获它,但是这不是必须的。假如实现了回调接口的子类里的方法出错,而且不是RuntimeException的子类,也就是必须捕获的异常,但是query()方法中在逻辑上是没有办法捕获它的。所以Rod_Johnson把接口定义成JdbcTemplate的inner interface。这就可以JdbcTemplate就可以捕获它。
   回调方法也是框架的一种基本方法,比如java.io.File类中的listFiles(FilenameFilter filter),FilenameFilter就是一个接口,我们实现这个接口中的方法accept(File dir, String name) ,这就是一个典型的回调方法。
   观察者模式的使用符合开闭原则,并且分离了关注点。这种对模块修改开发,影响关闭的原则促进了AOP面向方面编程的发展。Spring中的AOP可能就是这种思想的实现,个人猜测而已。    
    把方法的参数放在一个类中,这样以后要增加参数的话,不用修改方法签名,感觉很干净,唯一可能的缺点是可能对性能有所下降,不过很小。如果没有用EJB的话,应该差不多。

   对异常的处理,分为checked和unchecked异常,checked异常是继承java.lang.Exception的。Unchecked异常继承java.lang.RuntimeException。Rod_Johnson主张在对出现异常后,程序不能处理,只能给予没用的提示时用RuntimeException,因为RuntimeException容器会自动处理。关于异常的详细说明,我也没看明白,希望那位大虾能指点指点。

备注:本文主要内容来源于Rod_Johnson的大作,强烈建议看原版!

posted @ 2006-03-30 21:57 逝去的年华 阅读(1455) | 评论 (0)编辑 收藏

Template模式和Strategey模式

         在学习Spring的过程中经常看到一些大虾推荐阅读Rod_Johnson的<Expert_One-on-One_J2EE_Design_and_Development>书,据说此书的第四章每个学java人都要看看.好不容易搞到pdf版,可惜是E文的,中文的搞不到,没办法只好硬着头皮看下去。
   第四章主要讲的是面向对象的设计模式,怎么采用一致的编码公约,怎么利用也有的系统.这对于理解Spring框架有很大的帮助!因为这是Spring之父的编程思想。):
   关于接口的好处及组合模式的有点,我这里就不说了。
   Template模式:适用范围,我们知道某个业务或算法的步骤,但是不知道怎么把每步的顺序。Template模式采用在abstract类中有个Public and final的方法封装了调用每步的顺序,也就是说控制了工作流程。所有的继承类也就只要实现每步的具体方法。这是控制反转的一种表现,以前都是我们在程序中去调用API中的方法,现在是我们实现API某个类中的抽象方法给该类调用!这种控制反转的机制,是框架的代码基础.比如,EJB中的Init()和destory()方法等等.Spring框架中的对数据持久层的实现就是很好的例子!
下面把书中的例子COPY下:
  AbstractOrderEJB父类实现了商业逻辑,包括用户是否金额超现和对大的订单进行打折,palceOrder()方法就是那个工作流方法。

abstract   class  AbstractOrderEJB
{
    
public   final  Invoice placeOrder ( int  customerId, InvoiceItem[] items)
        
throws  NoSuchCustomerException, SpendingLimitViolation 
    
{
        
int  total  =   0 ;
        
for  ( int  i  =   0 ; i  <  items. length; i ++
        
{
            total 
+=  getItemPrice (items [i])  *  items [i] .getQuantity();
        }

        
if  (total  >  getSpendingLimit (customerId) )
        
{
            getSessionContext() .setRollbackOnly();
            
throw   new  SpendingLimitViolation (total, limit);
        }

        
else   if  (total  >  DISCOUNT_THRESHOLD) 
        
{
            
//  Apply discount to total
        }

        
int  invoiceId  =  placeOrder (customerId, total, items);
        
return   new  InvoiceImpl (iid, total);
    }


    
protected   abstract   int  getItemPrice(InvoiceItem item);

    
protected   abstract   int  getSpendingLimit(customerId) throws  NoSuchCustomerException;

    
protected   abstract   int  placeOrder( int  customerId,  int  total,InvoiceItem[] items);
  }

   getItemPrice,getSpendingLimit,placeOrder这三个方法,是protected and abstract的,由子类来实现。
   Strategey模式和Template模式比较相似.用Strategey模式对上个例子进行改造:把三个单独的方法放入一个接口中,工作流方法进行如下修改:

 1 public   class  OrderEJB
 2 {
 3      private  DataHelper dataHelper;
 4      public   void  setDataHelper (DataHelper newDataHelper) 
 5      {
 6          this .dataHelper  =  newDataHelper;
 7     }

 8      public   final  Invoice placeOrder ( int  customerId, InvoiceItem[] items)
 9          throws  NoSuchCustomerException, SpendingLimitViolation 
10      {
11          int  total  =   0 ;
12          for  ( int  i  =   0 ; i  <  items.length; i ++
13          {
14             total  +=   this .dataHelper.getItemPrice(items[i])  *
15             items[i].getQuantity();
16         }

17          if  (total  >   this .dataHelper.getSpendingLimit(customerId)) 
18          {
19             getSessionContext() .setRollbackOnly();
20              throw   new  SpendingLimitViolation(total, limit);
21         }
 
22          else   if  (total  >  DISCOUNT_THRESHOLD) 
23          {
24              //  Apply discount to total
25         }

26          int  invoiceId  =   this .dataHelper.placeOrder (customerId, total, items);
27          return   new  InvoiceImpl (iid, total);
28     }

29 }

   Stratery模式比Temlater模式复杂点,但是它具有更高的灵活性,对于实际项目一些流程的控制有很好的作用!这是本人的观点,不一定正确,仅供参考。
   
在下面的情况下,用Stratery模式比Temlater模式更好:
1,每步都是可变的
2,实现每步的类需要一个独立的继承体系
3,实现每步的类要和其他的类打交道
4,实现每步的类要实现多态性

备注:本文主要内容来源于Rod_Johnson的大作,强烈建议看原版!

posted @ 2006-03-29 20:49 逝去的年华 阅读(1475) | 评论 (0)编辑 收藏

程序员的个人发展

      这是我的blog的第一篇文章,转载一段网上的经典文章,时刻检查自己望这个方向努力。既然选择了远方,就要勇往直前!

技术&管理&做人&行业

每天晚上,请你问自己这些问题:
1, 今天我是否克服了技术上新的困难?
2, 今天我是否多读了一些新书?
3, 今天我是否就某方面的问题与人进行了交流?
4, 今天我是否多认识了一个新同事或新朋友并准备与他们保持联络?
5, 今天我是否更多的接触到身处的行业需求,现状,和发展?

精通技术

      精通技术是技术人员的根本要求,也是技术人员人生发展的必经之路,只有首先精确掌握一门技术,才能触类旁通的掌握其他技术。精通技术不仅仅是为了精通技术,而是为了触类旁通,为了掌握精通技术的学习方法,研究方法,体会身处技术顶点的感受和境界,这样,下一次准备或需要进入另一个领域时,才会有明确的目标。

      为了精通技术,就要有以工作为乐的精神。不主张过于频繁的换工作(常常被认为是不热爱工作,不适应环境,或者不忠诚的表现)。以工作为乐,才会投入更多的精力和时间,才能够飞快成长,成为该方面的能手。以工作为乐,是朝着技术高峰阔步迈进的享受过程。

      如果仅仅的是以工作为乐,仅仅号称自己喜欢工作,而没有“朝着技术高峰阔步迈进”,则是一种浪费。要做工作和生活的有心人,才不会迷信技术,才会避免骄傲,才不会在达到某个水平以后停步不前。不仅要做有心人,还要学会研究。研究该门技术的发展方向,该门技术最好的学习方法,在该门技术上取得突出成就的道路,和激励自己沿着正确的方向前进的诀窍。做好了这些问题的研究,就会在以工作为乐的境界中做出超凡的成绩。

总之,
1, 反对不认真对待技术。
2, 反对不热爱工作,一心旁鹜。
3, 做生活和工作的有心人。

懂得管理

      懂得管理,既要学会管理,也要学会配合管理。那些对所有人和所有事情都吹毛求疵的人是不适应社会的,也是不容易成功的。懂得管理,既要学会管理工程(进度,过程,资源,需求分析,客户交流),又要学会管理人。要重视团队建设,重视团队的合作,重视团队的文化建设,重视团队的凝聚力,重视管理者的个人感染力。

      在用户不能提出明确的需求的情况下,要综合经验,替用户提出明确的需求。

      符合标准的过程控制,方法论的实际应用可以引导工程有一个可期望的好结果。否则就是运气的功劳。
      资源的合理配置,建设一个每个人舒适工作的环境,不要让你的组员不得不总是把精力放在环境建设等问题上,是让人做出更大成绩的捷径。

      与人畅快交流的能力,成为软件人员必备的素质之一。懂得行业的知识就从这里开始。

      那些单纯学过管理的人,无论进入那一个行业,都需要不断的迅速的学习一些关于该行业的专门知识,至少是名词术语,基本原理,关键技术,主要应用。这样的了解初步管理知识的人,一定不要对技术人员指手画脚,否则一定得不到应有的认同,反之,如果他们从过程本身的流程或者方法论等方面提出建议,就可以更好的体现自己的价值。

进入行业

      软件工作,离不开行业,尤其是应用软件。一个仅仅懂得实现技术的人,是不够的。所以一定要拓展你的知识,对你所处在的行业有一个更全面,更准确,更实质性的了解。

      软件人员看到需求分析,常常想到如何去实现它,而不会认真的去研究这份需求,站在用户的角度上来做更多的工作,这是值得软件人才所注意的。

      研究你所在的行业,也需要有一种系统的方法。了解其中的关键点是进入这个行业的捷径。了解触及该行业更多方面的关键点,是掌握这个行业的必经之路。对该行业做系统的总结分析,是深入该行业的目的。初步的研究成果经过更多的提炼和交流,就会成为金子般的智慧。

以下是几点建议:

      从点滴做起。先做好那些你力所能及的工作。标准化你的行业。你所处的行业虽然确定,但是每一家公司的需求各不相同。掌握他们做事情的流程,可以帮助你做好标准化。同时学习那些该行业的标准,以用户的标准为标准,更加深刻的理解标准,是代替用户做好标准化的方法。
      掌握核心技术。任何行业都有核心技术。掌握某一项核心技术,就可以让你进入这个行业并在其中生存,反之仅仅浅尝辄止,就会让你遭遇失败,抱怨不公。

影响你职业发展的几项能力
1, 研究问题的能力
2, 影响他人的能力
3, 个人履历

请相信以下观念
1,教育不是万能的。希望学校或者任何一个教育机构为你准备所有的知识,能力,水平,是不可能的。最好的大学是自己和无字书。
2, 成长在工作中。工作中的表现和积累才是人生腾飞的实际动力。

从今天起,请做好
1, 培养你自己更广泛的兴趣,并坚持你的人生目标
2, 锻炼你的演讲能力
3, 多认识朋友,以他们为荣
4, 培养你的远见卓识


处处深入学习,跟踪技术顶峰!追求技术顶峰!!

转载自:http://gocom.primeton.com/blog/index.php?op=ViewArticle&articleId=15&blogId=9

posted @ 2006-02-28 22:30 逝去的年华 阅读(289) | 评论 (0)编辑 收藏