`
esffor
  • 浏览: 1367319 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多
问题的提出
分析与决策
1.       编写DAO的时候不要直接去使用hibernate或spring对hibernate的支持。
现在我们在编写DAO的时候普遍都是直接继承springhibernate的封装类HibernateDaoSupport,然后使用该类提供的诸如等等。另外,在使用方法实现一些更复杂的hibernate功能的时候还会使用hibernate的类,诸如Query, Session, Type等。这样直接使用springhibernate的类存在的问题在于,你的代码将不得不依赖与springhibernate的某个版本。比如说,现在hibernate3出来了,改动挺大,实际上最要命的是包结构,hibernate2的包结构是,然而hibernate3。同样,spring为了支持hibernate3,包名也改为。假如,你现在新开发一个项目,这没什么关系,如果是升级一个项目问题就来了。如果你希望将你的一个项目从hibernate2升级为hibernate3,你不得不修改DAO中所有对hibernatespring-hibernate的引用。如果你的代码中出现hibernate2hibernate3不兼容的方法和类,比如(在hibernate3中已经没有了),你还将不得不改写。那么你可能会说,我不会这样升级。如果你的软件生命周期有好多年,hibernate升级到4,升级到5,你还是依然使用hibernate2?如果你以这种方式开发一个平台,你能要求所有使用你平台的软件项目都只能使用hibernate2?更进一步说,我现在开发一个产品,今后的客户将是成千上万。经过12年我需要升级了,这时我的升级包有几十M,几乎把所有的DAO都换了个遍,这样的升级无异于重装。也许,有人会提出另一个方案,在HibernateDaoSupportDAO中间增加了一个基础类,这样将基础类中的,改为了,这样其下面继承的DAO就不用改动了。然而在源码上是小小的改动,但对于类来说,两个不同版本的其相关的属性和方法还是有不少变化,那么在基础类重新编译的同时,你的继承类重新编译否。既然已经重新编译了,因此你的所有DAO在升级的时候依然要打入升级包,问题依然存在。
以上问题,究其原因,是我们项目中的DAO依赖于hibernatespring,因为我们对它们的使用是继承,是一种很强的关联,就是一种依赖。我们只需要稍微进行一些调整,就可以解决这个问题,那就是不使用直接继承,而使用接口进行分离。可以使用Façade模式,先建立一个叫BasicDao的基础类,从名称我们可以看出,它是所有DAO的基础类,实现DAO操作所需的所有诸如等方法,除了一些基本的方法,诸如翻页查询、getCount、解析查询条件形成HQL语句等功能也在这里实现,但是不要使用与hibernatespring有关的任何方法和类。同时,BasicDao调用一个叫DaoSupport的接口,DaoSupport的接口则是提供持久化所需的基本方法,最原始的元素。然后,我为DaoSupport接口提供各种不同的实现,比如hibernate2的实现DaoSupportHibernateImphibernate3的实现DaoSupportHibernate3Imp,整个结构如下图所示。BasicDao可以使用hibernatespring提供的方法,但是不是直接使用,而是通过调用DaoSupport的实现类来使用。然而BasicDao到底是使用的那个实现类,我们通过springIoC,通过配置文件来决定到底使用哪个实现。同时,BasicDao也不要使用诸如SpringContext的类来实现IoC,而是通过建立方法,然后在spring配置文件中建立引用。
2.       编写Action的时候不要直接使用spring和spring的继承类
前面我说了应当避免DAO引用springhibernate及其继承类。同样的事情也发生在Action中。由于Action通常不纳入spring的管理,因此Action在通过spring调用某个BUS的时候,往往是去引用一个叫的类(spring的类的继承类然后使用它的方法。如此的使用,我们的Action将依赖与spring。我们同样可以使用一个叫BasicAction的父类,然后用一个接口来隔离spring。由于Action通常不纳入spring的管理,我们通过一个的配置文件来决定接口到底调用哪个实现类。这样的结构的另一个好处是,我们还可以将所有Action都必须使用的诸如写日志、用户校验、异常处理都放在父类BasicAction中,提高系统的可维护性。
 
3.       当BUS需要获取别的模块的数据的时候,不要直接去使用该模块的DAO
我举一个简单的例子:我需要设计一个软件评审的管理软件,该软件分为评审组织者制订评审计划、评审者分别填写评审表后由评审组织者汇总评审表、评审组织者制作评审报告。这是一个非常简单的项目,分成了三个人来完成。但是项目进行快结束的时候却出现了问题。填写评审表需要获得评审计划中的一些数据,制作评审报告的数据来源于评审表。项目组在开始编程前先开了一次会,大家约定好了各个部分的数据格式及其规则,然后开始工作。然而数天后项目组把各个模块整合以后发现,系统根本跑不起来,为什么呢?设计评审计划的人发现,所有评审计划应当按照产品编号来进行管理而不是项目编号。由于这个变更,填写评审表模块在待评审列表中什么都无法显示;同样,设计评审表的人发现,在一个评审计划中评审表与评审者不是一对多的关系,而是一对一的关系,因而修改了这两个表的关联。因为这样,在制作评审报告时就不能正确得到评审表数据。其实一个软件项目在整个进行过程中总是不断变更。我们需要做的不是去抑制这些变更,而应当是通过软件的结构去适应这些变更,即是降低各模块间的依赖(耦合),提高内聚。
拿这个实例来说,当评审表需要调用评审计划的数据的时候,不应当是自己写一个DAO去调用评审计划的数据,而应当是调用评审计划的接口,将这个任务交给评审计划类来完成。当评审报告需要调用评审表的数据的时候,同样应当去调用评审表的接口,由评审表来实现。同时,这种调用应当是去调用BUS层的接口。为什么呢?比如在评审计划中的一个业务逻辑是只有在评审计划发布以后才能制作评审表,那么怎样才是已发布的评审计划呢?这个业务逻辑应当由谁来定义?当然是评审计划。在什么地方定义?当然是BUS而不是DAO,因为DAO仅仅是实现数据的持久化,而BUS才是实现业务逻辑的地方。既然如此,如果评审表去调用评审计划的DAO,那么已发布评审计划的业务逻辑必然包含在了评审表的业务逻辑里了。我们假设有一天,已发布评审计划的业务逻辑发生变更了(实际上这样的会在你毫不经意间就发生了),编写评审计划的人会很快就修改了评审计划的业务实现并且测试通过了。他不知道评审表里也包含了这样的业务逻辑,因而修改后的程序在运行到评审表的时候就很可能会出错。不幸的是,在实际工作中,同样一个业务逻辑可能包含在无数个你可能知道,但你也可能不知道的代码中。这样的结构就是一个不易于维护的差的结构。
 
总结:从技术升级和需求变更两方面适应变化

软件开发专家Alistair Cockburn在《敏捷软件开发》中说过,软件在整个生命周期中变更是无时无刻不发生的。我认为,软件的变更一方面是技术的更新,今天我们使用 



分享到:
评论

相关推荐

    Struts+Spring+Hibernate+WebService集成架构.doc

    整个过程中,各层通过定义清晰的接口进行交互,确保了系统的松耦合和高内聚。 综上所述,Struts+Spring+Hibernate+WebService集成架构通过合理的分层设计,充分利用了各框架的优势,构建出了一个既高效又灵活的企业...

    Struts+hibernate+spring框架

    在请求处理过程中,Spring将负责创建和配置这些对象,从而实现了解耦合和高内聚的设计原则。 在MySQL作为数据库的情况下,SSH整合通常会涉及以下步骤: 1. **环境配置**:安装并配置JDK、Apache Tomcat服务器、...

    Struts+Spring+Hibernate+Freemarker新闻系统

    6. **整合应用优势**: 将Struts、Spring、Hibernate和Freemarker整合在一起,可以实现松耦合、高内聚的设计,提高代码的可维护性和可扩展性。此外,这四个框架都有丰富的社区支持和强大的功能,可以应对复杂的应用...

    jar包(struts2.0.8+spring2.0+hibernate3.2)

    这个压缩包“struts2.0.8+spring2.0+hibernate3.2”包含了这三个框架的特定版本,这将帮助开发者在构建基于Java的企业级应用程序时快速搭建环境。 **Struts2** 是一个用于构建企业级Web应用程序的开源MVC框架,它...

    struts+hibernate+spring集成教程

    6. **优势与最佳实践**:集成Struts、Hibernate和Spring可以实现松耦合、高内聚的设计,提高开发效率。在实际项目中,我们应遵循模块化、分层设计的原则,合理划分各层职责,并注意性能优化,如缓存策略、事务隔离...

    struts+hibernate+spring开发实例

    在这个过程中,不仅深入了解了每一层的作用和实现原理,还学习了如何通过这些技术框架来构建一个高内聚低耦合的应用程序。这种分层设计的思想对于未来开发复杂的企业级应用具有重要意义。 此外,实验还展示了如何...

    开发者突击 struts2+Spring+Hibernate 整合开发 投票管理系统

    这种整合能够充分利用各个框架的优势,实现松耦合、高内聚的设计,提高开发效率和代码质量。 首先,Struts2作为前端控制器,接收HTTP请求,解析用户输入,并调用相应的业务逻辑。它的拦截器机制使得我们可以添加...

    做struts2.0+spring+hibernate项目使用的jar包

    通过合理的配置和编程,可以构建出松耦合、高内聚的系统架构。 总的来说,Struts2.0+Spring+Hibernate的组合为Java Web开发提供了一个强大的解决方案,它可以帮助开发者快速地构建出健壮的、模块化的应用,同时也为...

    会员管理系统(struts+hibernate+spring)

    SSH框架结合使用,可以实现松耦合、高内聚的代码结构,提高开发效率和代码可维护性。同时,通过Spring的事务管理,保证了数据操作的原子性和一致性,提升了系统的稳定性。 综上所述,"会员管理系统(struts+...

    Struts+Hibernate+Spring实现的人力资源管理系统

    此外,Spring的集成能力使得Struts和Hibernate能无缝配合,构建出松耦合、高内聚的系统架构。 除了技术选型,本系统还包含了需求文档、数据库设计文档以及需求讲演PPT,这些都是项目开发的关键组成部分。需求文档...

    车辆管理系统(struts+hibernate+spring+oracle)130225.zip

    5. 整合框架:将Struts、Hibernate和Spring整合在一起,可以实现松耦合和高内聚的设计,提高系统的灵活性和可维护性。Spring可以管理和协调其他两个框架,使得业务逻辑和数据访问更加独立,同时也降低了系统的复杂性...

    会员管理系统(struts+hibernate+spring).zip

    Struts处理用户交互,Hibernate负责数据存储,Spring则协调整个系统的运行,形成了一种松耦合、高内聚的架构。这样的设计不仅提高了开发效率,还降低了系统维护和扩展的成本。 在实际开发中,会员管理系统可能包括...

    Spring+struts+hibernate 的 SSH教程

    SSH框架组合使用,可以实现松耦合、高内聚的代码结构,提高开发效率,便于团队协作和后期维护。同时,SSH提供了一套完整的解决方案,覆盖了从用户请求到数据持久化的整个流程。 总结,SSH教程是一个为初学者准备的...

    论坛系统(Struts 2+Hibernate+Spring实现)

    此外,SSH框架的集成使得论坛系统具备了良好的分层架构,Struts 2 在表现层提供视图控制,Hibernate 负责数据层的存储与检索,而Spring则在业务层协调各个组件的工作,形成了一种松耦合、高内聚的设计。这样的架构...

Global site tag (gtag.js) - Google Analytics