Java视线论坛 :: 阅读主题 - 结合struts和hibernate谈J2EE架构的数据表示

来源:百度文库 编辑:神马文学网 时间:2024/04/26 00:25:43
Java视线论坛
  使用帮助   搜索    会员列表    团队   注册     个人资料    我的BLOG  BLOG列表      登录   登录并检查站内短信 
Java视线论坛首页  -> 软件技术讨论区 ->  Hibernate与持久化 结合struts和hibernate谈J2EE架构的数据表示         阅读上一个主题 :: 阅读下一个主题   作者 正文 robbin
论坛管理员



性别:
年龄:30
十二宫图:
加入时间: 2003/09/07
文章: 2027
来自: 上海

时间: 2003-9-29 18:21:06    标题: 结合struts和hibernate谈J2EE架构的数据表示
在 struts+ hibernate 这种结构中,是不应该把Hibernate产生的PO直接传递给JSP的,不管他是Iterator,还是List,这是一个设计错误。

我来谈谈在J2EE架构中各层的数据表示方法:

Web层的数据表示是FormBean,数据来源于HTML Form POST
业务层的数据表示是VO
持久层的数据表示是PO,其数据来源于数据库,持久层的数据表示例如CMP

在一个规范的J2EE架构中,不同层的数据表示应该被限制在层内,而不应该扩散到其它层,这样可以降低层间的耦合性,提高J2EE架构整体的可维护性和可扩展性。比如说Web层的逻辑进行了修改,那么只需要修改FormBean的结构,而不需要触动业务层和持久层的代码修改。同样滴,当数据库表进行了小的调整,那么也只需要修改持久层数据表示,而不需要触动业务层代码和Web层代码。

不过由于Hibernate的强大功能,例如动态生成PO,PO的状态管理可以脱离Session,使得在应用了Hibernate的J2EE框架中,PO完全可以充当VO,因此我们下面把PO和VO合并,统称为PO。

先来谈谈ActionFormBean和持久层的PO之间的重大区别。

在简单的应用中,ActionFormBean和PO几乎是没有区别,所以很多人干脆就是用ActionFormBean来充当PO,于是ActionFormBean从JSP页面到Servlet控制层再到业务层,然后穿过持久层,最后一直映射到数据库表。真是一竿子捅到了底!

但是在复杂的应用中,ActionFormBean和PO是分离的,他们也不可能一样。ActionFormBean是和网页里面的Form表单一一对应的,Form里面有什么元素,Bean里面就有什么属性。而PO和数据库表对应,因此如果数据库表不修改,那么PO也不会修改,如果页面的流程和数据库表字段对应关系不一致,那么你又如何能够使用ActionFormBean来取代PO呢?

比如说吧,用户注册页面要求注册用户的基本信息,因此HTML Form里面包含了基本信息属性,于是你需要一个ActionFormBean来一一对应(注意:是一一对应),每个Bean属性对应一个文本框或者选择框什么的。

而用户这个持久对象呢?他的属性和ActionFormBean有什么明显不同呢?他会有一些ActionFormBean所没有的集合属性,比如说用户的权限属性,用户的组属性,用户的帖子等等。另外还有可能的是在ActionFormBean里面有3个属性,分别是用户的First Name, Middle Name, Last Name,而在我的User这个持久对象中就是一个 Name 对象属性。

假设我的注册页面原来只要你提供First Name,那么ActionFormBean就这一个属性,后来我要你提供全名,你要改ActionFormBean,加两个属性。但是这个时候PO是不应该修改滴,因为数据库没有改。

那么在一个完整的J2EE系统中应该如何进行合理的设计呢?

JSP(View) ---> ActionFormBean(Module) ---> Action(Control)

ActionFormBean是Web层的数据表示,它和HTML页面Form对应,只要Web页面的操作流程发生改变,它就要相应的进行修改,它不应该也不能被传递到业务层和持久层,否则一旦页面修改,会一直牵连到业务层和持久层的大面积的代码进行修改,对于软件的可维护性和可扩展性而言,是一个灾难,Actiont就是他的边界,到此为止!

Action(Web Control) ---> Business Bean ---> DAO ---> ORM --->DB

而PO则是业务层和持久层的数据表示,它在业务层和持久层之间进行流动,他不应该也不能被传递到Web层的View中去,而ActionServlet就是他的边界,到此为止!

然后来看一看整个架构的流程:

当用户通过浏览器访问网页,提交了一个页面。于是Action拿到了这个FormBean,他会把FormBean属性读出来,然后构造一个PO对象,再调用业务层的Bean类,完成了注册操作,重定向到成功页面。而业务层Bean收到这个PO对象之后,调用DAO接口方法,进行持久对象的持久化操作。

当用户查询某个会员的信息的时候,他用全名进行查询,于是Action得到一个UserNameFormBean包括了3个属性,分别是first name, middle name, last name,然后Action把UserNameFormBean的3个属性读出来,构造Name对象,再调用业务Bean,把Name对象传递给业务Bean,进行查询。

业务Bean取得Name(注意: Name对象只是User的一个属性)对象之后调用DAO接口,返回一个User的PO对象,注意这个User不同于在Web层使用的UserFormBean,他有很多集合属性滴。然后业务Bean把User对象返回给Action。

Action拿到User之后,把User的基本属性取出(集合属性如果不需要就免了),构造UserFormBean,然后把UserFormBean request.setAttribute(...),然后重定向到查询结果页面。

查询页面拿到request对象里面的ActionFormBean,自动调用tag显示之。

总结:

FormBean是Web层的数据表示,他不能被传递到业务层;PO是持久层的数据表示,在特定情况下,例如Hibernate中,他可以取代VO出现在业务层,但是不管PO还是VO都必须限制在业务层内使用,最多到达Web层的Control,绝不能被扩散到View去。

FormBean和PO之间的数据转化是在Action中进行滴。

BTW:

JDO1.x还不能像Hibernate功能这样强大,PO不能脱离持久层,所以必须在业务层使用VO,因此必须在业务层进行大量的VO和PO的转化操作,相对于Hibernate来说,编程比较烦琐。

当然咯,理论是一回事,实际操作也不一定非要这样干,你可以自行取舍,在实际项目中灵活一点,增加一点bad smell,提高开发效率。只不过在大型项目中最好还是严丝合缝,不然的话,改版的时候会痛苦的很滴。 返回顶端 huisky
Apache Tomcat



性别:
年龄:23
十二宫图:
加入时间: 2004/03/09
文章: 8


时间: 2004-3-11 22:06:02    标题:
感谢提供这篇文章!
我最近也是在研究struct+hibernate 的组合开发!
发现的问题就是楼主提出来的观点所能解决的! 返回顶端 denfard
Sun JDK






加入时间: 2003/10/02
文章: 1


时间: 2004-3-12 09:28:26    标题: Struts的Action是Control?
引用: 那么在一个完整的J2EE系统中应该如何进行合理的设计呢?

JSP(View) ---> ActionFormBean(Module) ---> Action(Control)

记得在一个文档里的讲解,说Action和ActionForm都是Model,ActionServlet才是Control。

如果你的理解是正确的话,为什么有人说把ActionForm和Action分开违反了OO的思想?似乎在JSF里边就没有这么做了。

能解释一下你的理解吗? 返回顶端 show90
Caucho Resin




年龄:32

加入时间: 2004/04/14
文章: 16


时间: 2004-4-26 09:11:44    标题:
刚刚在学HIBERNATE ,不知道RIBBIN 能不能提供这样的例子呢。 返回顶端 ygxdha
Caucho Resin






加入时间: 2004/04/05
文章: 17


时间: 2004-4-27 12:08:24    标题: Re: Struts的Action是Control?
denfard 写道: 引用: 那么在一个完整的J2EE系统中应该如何进行合理的设计呢?

JSP(View) ---> ActionFormBean(Module) ---> Action(Control)

记得在一个文档里的讲解,说Action和ActionForm都是Model,ActionServlet才是Control。

如果你的理解是正确的话,为什么有人说把ActionForm和Action分开违反了OO的思想?似乎在JSF里边就没有这么做了。

能解释一下你的理解吗?
记得在一个文档里的讲解,说Action和ActionForm都是Model,ActionServlet才是Control。
的确是这样划分mvc的,不过robbin估计是笔误吧。
而且,可以不把actionForm划分到m层里面,你画一下,三层之间的uml图,会发现actionForm只能数据的容器,在三层之间传递数据。具体将之放到那一层并不好。 返回顶端 stevendu
Apache Tomcat






加入时间: 2004/03/09
文章: 8


时间: 2004-4-28 08:44:41    标题:
我是这么考虑的,其实Action才是真正的Controller, ActionServlet只不过是一个接收器而已,最终的分发是Action完成的。 返回顶端 lyl
Sun JDK



性别:


加入时间: 2004/04/29
文章: 2


时间: 2004-4-29 13:29:58    标题:
stevendu 写道: 我是这么考虑的,其实Action才是真正的Controller, ActionServlet只不过是一个接收器而已,最终的分发是Action完成的。

分发是在RequestProcessor中完成的,action只是实现真正的业务逻辑.

我一般都是在actionform中加个构造函数,把PO转化为form,再加个把PO转化为form的方法就行了. 返回顶端 freeman
Sun JDK






加入时间: 2004/01/31
文章: 4


时间: 2004-5-04 15:00:10    标题:
lyl 写道: stevendu 写道: 我是这么考虑的,其实Action才是真正的Controller, ActionServlet只不过是一个接收器而已,最终的分发是Action完成的。

分发是在RequestProcessor中完成的,action只是实现真正的业务逻辑.

我一般都是在actionform中加个构造函数,把PO转化为form,再加个把PO转化为form的方法就行了.

业务逻辑应该写在action中吗? 返回顶端 slovenboy
Sybase EAServer



性别:


加入时间: 2004/05/07
文章: 86
来自: slovenboy.blogdriver.com

时间: 2004-5-07 11:29:48    标题: Re: 结合struts和hibernate谈J2EE架构的数据表示
[quote="robbin"]在 struts+ hibernate 这种结构中,是不应该把Hibernate产生的PO直接传递给JSP的,不管他是Iterator,还是List,这是一个设计错误。

我来谈谈在J2EE架构中各层的数据表示方法:

Web层的数据表示是FormBean,数据来源于HTML Form POST
业务层的数据表示是VO
持久层的数据表示是PO,其数据来源于数据库,持久层的数据表示例如CMP
......
先来谈谈ActionFormBean和持久层的PO之间的重大区别。

.........

那么在一个完整的J2EE系统中应该如何进行合理的设计呢?

JSP(View) ---> ActionFormBean(Module) ---> Action(Control)

ActionFormBean是Web层的数据表示,它和HTML页面Form对应,只要Web页面的操作流程发生改变,它就要相应的进行修改,它不应该也不能被传递到业务层和持久层,否则一旦页面修改,会一直牵连到业务层和持久层的大面积的代码进行修改,对于软件的可维护性和可扩展性而言,是一个灾难,Actiont就是他的边界,到此为止!

Action(Web Control) ---> Business Bean ---> DAO ---> ORM --->DB

而PO则是业务层和持久层的数据表示,它在业务层和持久层之间进行流动,他不应该也不能被传递到Web层的View中去,而ActionServlet就是他的边界,到此为止!

然后来看一看整个架构的流程:

......

查询页面拿到request对象里面的ActionFormBean,自动调用tag显示之。

总结:

FormBean是Web层的数据表示,他不能被传递到业务层;PO是持久层的数据表示,在特定情况下,例如Hibernate中,他可以取代VO出现在业务层,但是不管PO还是VO都必须限制在业务层内使用,最多到达Web层的Control,绝不能被扩散到View去。

FormBean和PO之间的数据转化是在Action中进行滴。
..........
[quote]

Robbin写的很好,但是我还是忍不住说两句。

引用: JSP(View) ---> ActionFormBean(Module) ---> Action(Control)

我想说说关于ActionFormBean定义为Module的问题。前一段时间在Blogdriver上有很多朋友的Blog上提到MVC的问题。没记错的话Gigix和Ozzzzz认为MVC就是表示层的东西,不涉及业务逻辑方面,认为MVC是多层架构中表示层的架构。但从网上查看一些资料MVC实际上应该是三层,而不是只在表示层(我个人也是这么认为的)。如果MVC中V表示的是表示层的,那么ActionFormBean不是M,尽管V中也有数据,但那是表示层的,PO等才是M。
所以如果使用Struts/Hibernate的时候,MVC应该是这样分割:

Struts(V) -> PO/Hibernate(M) -> StrutsController(C).

上一次由slovenboy于2004-5-07 周五, 上午11:51修改,总共修改了1次 返回顶端 Sayor
IBM Webshpere



性别:
年龄:25
十二宫图:
加入时间: 2003/11/26
文章: 212
来自: 深圳

时间: 2004-5-07 11:44:39    标题: Re: 结合struts和hibernate谈J2EE架构的数据表示
slovenboy 写道:

Robbin写的很好,但是我还是忍不住说两句。

引用: JSP(View) ---> ActionFormBean(Module) ---> Action(Control)

我想说说关于ActionFormBean定义为Module的问题。前一段时间在Blogdriver上有很多朋友的Blog上提到MVC的问题。没记错的话Gigix和Ozzzzz认为MVC就是表示层的东西,不涉及业务逻辑方面,认为MVC是多层架构中表示层的架构。但从网上查看一些资料MVC实际上应该是三层,而不是只在表示层(我个人也是这么认为的)。如果MVC中V表示的是表示层的,那么ActionFormBean不是M,尽管V中也有数据,但那是表示层的,PO等才是M。
所以如果使用Struts/Hibernate的时候,MVC应该是这样分割:

Struts(V) -> PO/Hibernate(M) -> StrutsController(C).

好像M应该是持有业务逻辑的那些类,在struts+hibernate不论ActionForm还是po都不是M。 返回顶端 xanada
Macromedia JRun






加入时间: 2004/02/29
文章: 70


时间: 2004-5-08 04:12:38    标题: Re: 结合struts和hibernate谈J2EE架构的数据表示
slovenboy 写道: Struts(V) -> PO/Hibernate(M) -> StrutsController(C)

你不觉得这样的分割很生硬吗?

透明和胖子认为Struts的MVC是表示层的东西,不涉及业务逻辑方面。其实重点是在后半句,即Struts中不应涉入业务逻辑。换言之,在Action中实现业务逻辑是错误的。

如果一定要分成三层,而不是四层或更多层,我对MVC的理解是:
BusinessDelegeClass + Hibernate(M) -> JSP(V) -> ActionServlet + Action(C) 返回顶端 slovenboy
Sybase EAServer



性别:


加入时间: 2004/05/07
文章: 86
来自: slovenboy.blogdriver.com

时间: 2004-5-08 12:58:17    标题:
xanada
我想,我们说的是一个问题,如果一定要区分Controler,我想最理想的方法是使用Struts的子模块功能,这样一个应用就可以有一个Controler.
至于JSP是V的说法我不赞同,Struts本身就是V.
Struts中的JSP/ActionFormBean等都是V.Struts中的Action不能定义为C,他只是解析ActionFormBean中的数据,将V中的数据转化到业务逻辑所需要的格式。Struts中是没有M的,如果ActionFormBean算作M,也只能算作V的M.其实在MVC的任何一部分都有数据。 返回顶端 slovenboy
Sybase EAServer



性别:


加入时间: 2004/05/07
文章: 86
来自: slovenboy.blogdriver.com

时间: 2004-5-08 13:02:35    标题: Re: 结合struts和hibernate谈J2EE架构的数据表示
sayor 写道: slovenboy 写道:

Robbin写的很好,但是我还是忍不住说两句。

引用: JSP(View) ---> ActionFormBean(Module) ---> Action(Control)

我想说说关于ActionFormBean定义为Module的问题。前一段时间在Blogdriver上有很多朋友的Blog上提到MVC的问题。没记错的话Gigix和Ozzzzz认为MVC就是表示层的东西,不涉及业务逻辑方面,认为MVC是多层架构中表示层的架构。但从网上查看一些资料MVC实际上应该是三层,而不是只在表示层(我个人也是这么认为的)。如果MVC中V表示的是表示层的,那么ActionFormBean不是M,尽管V中也有数据,但那是表示层的,PO等才是M。
所以如果使用Struts/Hibernate的时候,MVC应该是这样分割:

Struts(V) -> PO/Hibernate(M) -> StrutsController(C).

好像M应该是持有业务逻辑的那些类,在struts+hibernate不论ActionForm还是po都不是M。
PO只是M的一部分,在PO之上,也就是使用PO对象的那些类才是真正的M
.而Action才是使用M的地方,如果在Action中直接使用PO就是不太符合MVC的,除非项目组扩展了PO。比如所有的PO都实现了一定的业务逻辑接口。 返回顶端 eckal
Caucho Resin



性别:


加入时间: 2004/05/08
文章: 16


时间: 2004-5-08 20:05:36    标题: 为何不用webwork和hibernate组合呢?
webwork比struts好用多了,而且view层完全分离c层,不象struts绑定在form上,还有很多的灵活性

如果你准备学strtus还不如开始学webwork,使用更方便,配置更简单 返回顶端 slovenboy
Sybase EAServer



性别:


加入时间: 2004/05/07
文章: 86
来自: slovenboy.blogdriver.com

时间: 2004-5-09 12:31:54    标题:
Webwork的确比Struts好;JSF出来后,不知道Struts2.0是否还会发布了。就连Struts的作者也觉得这个FormBean很有问题。其实有一个解决方法就是让PO等实现FormBean接口。这样就可以不单独写FormBean了,也不需要做那么多的类型转换。 返回顶端
显示文章:   
    Java视线论坛首页  -> 软件技术讨论区 ->  Hibernate与持久化 第1页,共4
 
论坛转跳:  
不能在本论坛发表新主题
不能在本论坛回复主题
不能在本论坛编辑自己的文章
不能在本论坛删除自己的文章
不能在本论坛发表投票
不能在这个论坛添加附件
可以在这个论坛下载文件

沪ICP备05023328号 phpBB