论坛首页 Java企业应用论坛

如何在struts+spring+hibernate的框架下构建低耦合高内聚的软件

浏览 27380 次
精华帖 (1) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-02-01  
非常高兴能和Allen朋友探讨技术问题 。现在在软件行业比较流行的一句话是“拥抱变化”。我们现在面临着来自客户来自我们的市场对我们提出的变化,关于这个问题的讨论我在《(原创)一个优秀软件开发人员的必修课:GRASP(3)高内聚》中进行了详细描述。我们现在要做的是在变化到来的时候,我们能够付出最小的代价适应变化。我们使用Spring和Hibernate可以帮助我们更加适应这些变化,但仅仅使用Spring和Hibernate技术是不够的,我们还要学会仔细去组织我们的项目。想像一下吧,如果我们使用hibernate2开发的项目现在需要换成hibernate3你需要修改些什么。如果按照我们过去的写法,每个持久化实体一个DAO,那么我们将有诸如StudentDao,TeacherDao,ClassDao等等许多个dao,稍微大一点儿的项目就可能有几十上百个dao。如果因为hibernate的变更使我的这些dao都需要修改,这样的变更带给我们的代价就大了。假如我们通过合理的软件构造,仅仅只修改了DaoSupport的配置和它的实现,这样的变更就仅仅在3、4个文件的变更上,代价是否很小。开发的代价小了,测试的代价是否也就变小?
但是,随着hibernate的越来越傻瓜,我们开始思考我们是不是可以不为每个实体制作dao,而是整个项目就一个dao。这样的做我至今还没有尝试过但至少理论上似乎可行。如果要这样做,即使hibernate变更了也只与那一个dao有关,我们变更的代价就很小了,代码的组织就不必如此复杂了。
0 请登录后投票
   发表时间:2007-02-01  
楼主介绍下webwork+spring+hibernate的配置嘛。
0 请登录后投票
   发表时间:2007-02-02  
fangang 写道
我们现在要做的是在变化到来的时候,我们能够付出最小的代价适应变化。我们使用Spring和Hibernate可以帮助我们更加适应这些变化,但仅仅使用Spring和Hibernate技术是不够的,我们还要学会仔细去组织我们的项目。想像一下吧,如果我们使用hibernate2开发的项目现在需要换成hibernate3你需要修改些什么。如果按照我们过去的写法,每个持久化实体一个DAO,那么我们将有诸如StudentDao,TeacherDao,ClassDao等等许多个dao,稍微大一点儿的项目就可能有几十上百个dao。如果因为hibernate的变更使我的这些dao都需要修改,这样的变更带给我们的代价就大了。假如我们通过合理的软件构造,仅仅只修改了DaoSupport的配置和它的实现,这样的变更就仅仅在3、4个文件的变更上,代价是否很小。开发的代价小了,测试的代价是否也就变小?

楼主所指的“我们过去的写法”很可能是说——DAO层中的每一个DAO都分别继承了HibernateDaoSupport,这样导致升级Hibernate依赖或者Spring依赖的时候便不得不提交全新的整个DAO层。

请注意:
每一次升级可以“仅在3、4个文件的变更上”,并不是因为“DAO不直接去使用hibernate或spring对hibernate的支持”造成的,而正是由于楼主所倡导的一个BasicDao基类(及其对应不同版本的Hibernate就采用不同的DaoSupportHibernatexImp)就可以提供全套CRUD无忧的模式。



我们此时就可以讨论一下只用一个持久化操作基类(BasicDao)来完成全套持久化动作的情形:

在DaoSupportHibernateImp或者DaoSupportHibernate3Imp、DaoSupportHibernate4Imp中实现DaoSupport,并且将其以Spring IoC的方式提供给BasicDao。这样一来,所有继承了BasicDao的DAO子类就可以轻松地获得CRUD的能力而又不用同Spring和Hibernate耦合在一起……

那么这样的方式与现在普遍采用的“BasicDao基类继承自HibernateDaoSupport(从而实现基本的CRUD方法),而下面的所有DAO子类又都继承BasicDao”套路有很大的区别吗?

我想,楼主的思路是尽可能使得BasicDao进一步跟以往的依赖解耦。这样在升级的时候除了新的jar包以外,更新的只是Spring的配置文件和一个DaoSupportHibernatexImp的class file,而整个DAO层都可以巍然屹立、不必动一根毫毛。

但是采用了“BasicDao基类继承自HibernateDaoSupport”的套路时,DAO层需要更新的也仅仅是BasicDao一个类而已……
0 请登录后投票
   发表时间:2007-02-02  
Allen 写道
但是采用了“BasicDao基类继承自HibernateDaoSupport”的套路时,DAO层需要更新的也仅仅是BasicDao一个类而已……

谢谢Allen跟我讨论这个问题。我们过去也是使用BasicDao基类直接继承HibernateDaoSupport,起初的想法也是只要更新了BasicDao就可以了,但实际情况却并未所愿,问题就在基类变了,子类是否需要重新编译。如果我们变更了基类,变更后的基类的方法、属性与原基类不同,而我们的子类(不论是直接还是间接)不重新编译,还是使用原来的编译后的文件,那么我们的项目在运行的时候会发生一些莫名其妙的、谁都说不清的问题。正因为如此,不只一个软件设计大师在书中提到,继承是一种强依赖,需要慎用。解决继承的问题的一个比较好的方法就是接口。
0 请登录后投票
   发表时间:2007-02-02  
我按照我的思路写了一个我的实现,放在我的文章中(Spring-Hibernate.rar),水平有限,仅供大家参考。 
0 请登录后投票
   发表时间:2007-02-02  
好啊.不错.顶
0 请登录后投票
   发表时间:2007-02-02  
fangang 写道
Allen 写道
但是采用了“BasicDao基类继承自HibernateDaoSupport”的套路时,DAO层需要更新的也仅仅是BasicDao一个类而已……

谢谢Allen跟我讨论这个问题。我们过去也是使用BasicDao基类直接继承HibernateDaoSupport,起初的想法也是只要更新了BasicDao就可以了,但实际情况却并未所愿,问题就在基类变了,子类是否需要重新编译。如果我们变更了基类,变更后的基类的方法、属性与原基类不同,而我们的子类(不论是直接还是间接)不重新编译,还是使用原来的编译后的文件,那么我们的项目在运行的时候会发生一些莫名其妙的、谁都说不清的问题。正因为如此,不只一个软件设计大师在书中提到,继承是一种强依赖,需要慎用。解决继承的问题的一个比较好的方法就是接口。


这个问题很容易解决,BasicDao(以及其子类们)均实现了某一个接口,DAO们需要使用到的方法在接口中定义好就行了……
0 请登录后投票
   发表时间:2007-02-02  
赞Allen,你这样做也是可以的。我的主要意思就是项目中那些实现具体业务的类不要直接继承和使用spring和hibernate的类和方法,而是通过接口进行隔离。至于如何实现当然是仁者见仁,智者见智了。
0 请登录后投票
   发表时间:2007-02-02  
支持原创@_@
0 请登录后投票
   发表时间:2007-02-03  
前段时间公司架构师搭出了类似楼主想法的框架,不过,没看懂他那样做的用途,今天得见楼主赐教,恍然大悟。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics