问题的提出
分析与决策
1.
编写DAO的时候不要直接去使用hibernate或spring对hibernate的支持。
现在我们在编写
DAO的时候普遍都是直接继承
spring对
hibernate的封装类
HibernateDaoSupport,然后使用该类提供的诸如
等等。另外,在使用
方法实现一些更复杂的
hibernate功能的时候还会使用
hibernate的类,诸如
Query, Session, Type等。这样直接使用
spring和
hibernate的类存在的问题在于,你的代码将不得不依赖与
spring和
hibernate的某个版本。比如说,现在
hibernate3出来了,改动挺大,实际上最要命的是包结构,
hibernate2的包结构是
,然而
hibernate3是
。同样,
spring为了支持
hibernate3,包名也改为
。假如,你现在新开发一个项目,这没什么关系,如果是升级一个项目问题就来了。如果你希望将你的一个项目从
hibernate2升级为
hibernate3,你不得不修改
DAO中所有对
hibernate和
spring-hibernate的引用。如果你的代码中出现
hibernate2与
hibernate3不兼容的方法和类,比如
(在
hibernate3中已经没有了)
,你还将不得不改写。那么你可能会说,我不会这样升级。如果你的软件生命周期有好多年,
hibernate升级到
4,升级到
5,你还是依然使用
hibernate2?如果你以这种方式开发一个平台,你能要求所有使用你平台的软件项目都只能使用
hibernate2?更进一步说,我现在开发一个产品,今后的客户将是成千上万。经过
1、
2年我需要升级了,这时我的升级包有几十
M,几乎把所有的
DAO都换了个遍,这样的升级无异于重装。也许,有人会提出另一个方案,在
HibernateDaoSupport与
DAO中间增加了一个基础类,这样将基础类中的
,改为了
,这样其下面继承的
DAO就不用改动了。然而在源码上是小小的改动,但对于类来说,两个不同版本的
其相关的属性和方法还是有不少变化,那么在基础类重新编译的同时,你的继承类重新编译否。既然已经重新编译了,因此你的所有
DAO在升级的时候依然要打入升级包,问题依然存在。
以上问题,究其原因,是我们项目中的
DAO依赖于
hibernate和
spring,因为我们对它们的使用是继承,是一种很强的关联,就是一种依赖。我们只需要稍微进行一些调整,就可以解决这个问题,那就是不使用直接继承,而使用接口进行分离。可以使用
Façade模式,先建立一个叫
BasicDao的基础类,从名称我们可以看出,它是所有
DAO的基础类,实现
DAO操作所需的所有诸如
、
、
、
等方法,除了一些基本的方法,诸如翻页查询、
getCount、解析查询条件形成
HQL语句等功能也在这里实现,但是不要使用与
hibernate或
spring有关的任何方法和类。同时,
BasicDao调用一个叫
DaoSupport的接口,
DaoSupport的接口则是提供持久化所需的基本方法,最原始的元素。然后,我为
DaoSupport接口提供各种不同的实现,比如
hibernate2的实现
DaoSupportHibernateImp、
hibernate3的实现
DaoSupportHibernate3Imp,整个结构如下图所示。
BasicDao可以使用
hibernate或
spring提供的方法,但是不是直接使用,而是通过调用
DaoSupport的实现类来使用。然而
BasicDao到底是使用的那个实现类,我们通过
spring的
IoC,通过配置文件来决定到底使用哪个实现。同时,
BasicDao也不要使用诸如
SpringContext的类来实现
IoC,而是通过建立
和
方法,然后在
spring配置文件中建立引用。
2.
编写Action的时候不要直接使用spring和spring的继承类
前面我说了应当避免
DAO引用
spring或
hibernate及其继承类。同样的事情也发生在
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,
那么已发布评审计划的业务逻辑必然包含在了评审表的业务逻辑里了。我们假设有一天,已发布评审计划的业务逻辑发生变更了(实际上这样的会在你毫不经意间就
发生了),编写评审计划的人会很快就修改了评审计划的业务实现并且测试通过了。他不知道评审表里也包含了这样的业务逻辑,因而修改后的程序在运行到评审表
的时候就很可能会出错。不幸的是,在实际工作中,同样一个业务逻辑可能包含在无数个你可能知道,但你也可能不知道的代码中。这样的结构就是一个不易于维护
的差的结构。
总结:从技术升级和需求变更两方面适应变化
分享到:
相关推荐
在IT行业中,构建一个低耦合、高内聚的软件架构是至关重要的,因为它能确保系统的可维护性、可扩展性和灵活性。Struts、Spring和Hibernate是Java领域中三个非常著名的开源框架,它们分别在MVC(Model-View-...
整个过程中,各层通过定义清晰的接口进行交互,确保了系统的松耦合和高内聚。 综上所述,Struts+Spring+Hibernate+WebService集成架构通过合理的分层设计,充分利用了各框架的优势,构建出了一个既高效又灵活的企业...
在请求处理过程中,Spring将负责创建和配置这些对象,从而实现了解耦合和高内聚的设计原则。 在MySQL作为数据库的情况下,SSH整合通常会涉及以下步骤: 1. **环境配置**:安装并配置JDK、Apache Tomcat服务器、...
6. **整合应用优势**: 将Struts、Spring、Hibernate和Freemarker整合在一起,可以实现松耦合、高内聚的设计,提高代码的可维护性和可扩展性。此外,这四个框架都有丰富的社区支持和强大的功能,可以应对复杂的应用...
这个压缩包“struts2.0.8+spring2.0+hibernate3.2”包含了这三个框架的特定版本,这将帮助开发者在构建基于Java的企业级应用程序时快速搭建环境。 **Struts2** 是一个用于构建企业级Web应用程序的开源MVC框架,它...
6. **优势与最佳实践**:集成Struts、Hibernate和Spring可以实现松耦合、高内聚的设计,提高开发效率。在实际项目中,我们应遵循模块化、分层设计的原则,合理划分各层职责,并注意性能优化,如缓存策略、事务隔离...
通过Struts,我们可以清晰地划分出模型层、视图层和控制器层,实现了代码的高内聚和低耦合。 #### Spring+Hibernate+Struts集成开发示例 在给定的代码片段中,我们看到了几个典型的Struts Action类:`...
在这个过程中,不仅深入了解了每一层的作用和实现原理,还学习了如何通过这些技术框架来构建一个高内聚低耦合的应用程序。这种分层设计的思想对于未来开发复杂的企业级应用具有重要意义。 此外,实验还展示了如何...
这种整合能够充分利用各个框架的优势,实现松耦合、高内聚的设计,提高开发效率和代码质量。 首先,Struts2作为前端控制器,接收HTTP请求,解析用户输入,并调用相应的业务逻辑。它的拦截器机制使得我们可以添加...
通过合理的配置和编程,可以构建出松耦合、高内聚的系统架构。 总的来说,Struts2.0+Spring+Hibernate的组合为Java Web开发提供了一个强大的解决方案,它可以帮助开发者快速地构建出健壮的、模块化的应用,同时也为...
SSH框架结合使用,可以实现松耦合、高内聚的代码结构,提高开发效率和代码可维护性。同时,通过Spring的事务管理,保证了数据操作的原子性和一致性,提升了系统的稳定性。 综上所述,"会员管理系统(struts+...
此外,Spring的集成能力使得Struts和Hibernate能无缝配合,构建出松耦合、高内聚的系统架构。 除了技术选型,本系统还包含了需求文档、数据库设计文档以及需求讲演PPT,这些都是项目开发的关键组成部分。需求文档...
5. 整合框架:将Struts、Hibernate和Spring整合在一起,可以实现松耦合和高内聚的设计,提高系统的灵活性和可维护性。Spring可以管理和协调其他两个框架,使得业务逻辑和数据访问更加独立,同时也降低了系统的复杂性...
Struts处理用户交互,Hibernate负责数据存储,Spring则协调整个系统的运行,形成了一种松耦合、高内聚的架构。这样的设计不仅提高了开发效率,还降低了系统维护和扩展的成本。 在实际开发中,会员管理系统可能包括...
SSH框架组合使用,可以实现松耦合、高内聚的代码结构,提高开发效率,便于团队协作和后期维护。同时,SSH提供了一套完整的解决方案,覆盖了从用户请求到数据持久化的整个流程。 总结,SSH教程是一个为初学者准备的...
此外,SSH框架的集成使得论坛系统具备了良好的分层架构,Struts 2 在表现层提供视图控制,Hibernate 负责数据层的存储与检索,而Spring则在业务层协调各个组件的工作,形成了一种松耦合、高内聚的设计。这样的架构...