层次架构的困惑

11-12-12 edison87915
介绍一下项目的现状先:

大体介绍:

表示层使用JSP,控制层使用STRUTS2,业务逻辑层使用自己封装的service类,持久层使用SPRING的JDBCTemplate封装SQL。

我现在的调用流程是这样的:

JSP(表单参数[参数形式:model.propertyName])--->ACTION(引用一个实体对象作为成员属性,struts2框架自动封装请求参数到实体对象)

--->调用service层的业务逻辑方法(层之间的参数传递依然是ACTION中封装的实体对象)---->service方法处理实体对象(实体对象可能嵌套)并调用多个DAO操作,且封装事务

--->DAO操作(从service层传过来的参数依然是ACTION中的实体对象,只是由service处理过了)

也就是说,层与层之间的接口的参数,我都使用了一个实体对象(当然实体对象会有嵌套关系,这样就可以操作多个实体),

或者在明确了参数仅需要ID的时候,参数为int型的ID(如:根据ID查询某条记录的详细信息时)

有几个困惑如下:

1. 表示层的表单参数的name感觉依赖于实体对象,尤其是实体嵌套的情况,比如某个表单项可能要这样写:name=user.department.deptName,甚至更长.

想问一下,这样好吗?表单参数和实体类属性纠缠在一起

2. 查询的时候,我喜欢直接使用spring的jdbcTemplate封装,使用queryForList等方法,直接返回LIST或MAP,从DAO方法返到SERVICE方法一直到ACTION中,

再将LIST或MAP添加到request中,在JSP页面上,直接使用EL表达式${list.数据库字段名}来显示

这样有个坏处,表示层直接和数据库字段扯在一起了...但是确实方便,想请教一下,老师们是怎么做的?

是不是这样:DAO负责从数据库中select数据,并封装成相应的实体对象或实体对象集合,然后返回到页面去展示吗?

3. 接着问题2,想问一下,查询得到的数据,有没有一种办法,可以灵活动态的定制字段列表,比如同一个查询,但是我需要的显示字段不同,

类似于[粗略展示记录列表]和[某记录的详细信息]这两种情况

我目前是将所有的字段全查出,封装成list或map,一并送去表示层,需要的显示,不需要的就不显示,这样应该是浪费传输资源的吧...

4. 是不是我的这种做法,实体对象就是传说中的DTO ? 我这种情况是否属于DTO满天飞的情况....老师指点啊

5. 看了不少相关文章,记得文章中说过,使用Hibernate的情况,实体对象的持久性质(如ID),不应该带到表示层去,应该剥离持久性质再传到表示层去显示...

这里有个疑问:比如我选中某条记录进行修改,步骤是:

1.根据选中记录的ID取出记录的详细信息并显示--->2.修改详细信息--->3.请求ACTION-->4.业务逻辑-->5.DAO做出修改

其中步骤2修改的页面中,肯定要保存一个hidden表单项---即该记录的ID,以便请求修改时知道所修改的是哪个记录?

老师们,耽误时间指点一下了...多谢!

[该贴被edison87915于2011-12-12 20:04修改过]

    

samzhouzl
2011-12-12 21:00
同志, 关于您的困惑, 我有以下几点建议, 纯属个人意见.

从您描述的这个情况来看, 其实你的问题只出现在2个地方, 1是架构上的数据传输. 纠正您的一个错误. DTO 是 Data Transfer Object, 数据传输对象, 并不是您说的实体对象. 2. Struts2 View层没有理解透和学习透.

以下对应您提出的困惑.

1. 对于Struts2的View层, 您的这个问题早意见在Struts2中解决, 只是您还不完全熟悉它的标签. OGNL可以处理这种常见的情况. 配合Struts2标签可以直接将"深对象"(引用比较深层次)放在值栈上. 方便读取和赋值. 在您的JSP上也很方便的运用. 具体您可以去查阅Struts2 文档. 在下不便说透.

2. 3.4.5这几个问题. 我想给出处于同一个根源的答案. 现在基于3层的开发模式很是流行. 但是有些老师只是教授了大家如何实现3层, 并没有结合整个项目和对象生命周期来探讨在层之间传输对象的最佳实践. 这里还是给出一个指引, 您去熟悉了DTO在回想您的问题. 答案迎刃而解.

banq
2011-12-13 09:10
2011年12月12日 20:02 "@edison87915"的内容
表单参数和实体类属性纠缠在一起 ...

楼上回答挺好,我补充一下,在复杂系统下,表单参数确实不应该和实体类纠缠在一起,可以专门建立一个表单参数。

查询时是否让数据表字段直接和界面耦合的问题,如果采取CQRS,也就是读写分离架构,那么为了报表输出或各种查询灵活性,读操作直接和数据表字段耦合也是正常的;

但是写操作需要在界面和数据库持久层之间有一个领域层,实体对象属于领域层的,写事件专门针对领域层的实体状态操作。

这样架构为:

Jsp --> Action ---> Service接口 -- >调用领域层中业务逻辑方法 --->仓储。

这个架构和你目前的区别是Service层,在Service层不应该直接加入业务逻辑,而是调用领域层,实体属于领域层,持久化DAO操作属于实体对象的一个行为职责,实体对象可能还有其他职责比如规则约束等其他业务逻辑行为实现。

相关帖:OOD vs SOA

也可参加这个重构架构帖子,亮点是:原来service只是作为提供业务的服务对象,而不是在里面实现业务的地方:http://www.jdon.com/jivejdon/thread/43502#23137901

[该贴被banq于2011-12-13 09:25修改过]

louisni
2011-12-13 09:20
banq大哥,小弟在此探讨下,领域层,相当于在数据层和服务层之间再架起一层。而这层中的业务逻辑可以放在内存中来处理。

banq
2011-12-13 09:27
2011年12月13日 09:20 "@louisni"的内容
,领域层,相当于在数据层和服务层之间再架起一层。而这层中的业务逻辑可以放在内存中来处理。 ...

可以这么理解,读操作就直接耦合数据库,充分利用关系数据库的数据相关性能力,然后在写操作中引入异步事件(根据领域对象的状态对一致性要求高低),过渡到CQRS或Event Sourcing。

猜你喜欢
2Go 1 2 下一页