精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-06-09
这么过来的,o/r mapping 采用的是hibernate 分页是后台分页,前台写了一个taglib。 问题: 因为分页的代码在后台基本上是一样的,唯一的区别是class参数不同(hibernate list 函数的参数) 所以我想如果每个流程都按 facade->bo->dao 上添加翻页的功能,觉得代码重用上做的非常不好, 但如果给facade,bo,dao每一层都添加接口(然后使用骨架类)然后各层都继承各自的骨架类,并层层的把查询条件和分页条件传递下来,我觉得也是比较累赘。(代码可以写自动生成器,主要是结构看起来不太舒服) 其实很简单的方法就是在taglib中直接调用DAO,(就分页这一块这么做) 通用的taglib+通用的分页代码,和功能模块,这样实现起来是最简单的。 不过这样就跳过了统一的facade接口,又违反了分层体系的原则,也不是我所愿意见到的。。。 我无法作出比较好的权衡判断(请大家给我一些意见) ps:我的技术总监倾向于结构清晰>代码量减轻。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-06-09
补充一点
dlee提出的xmlhttp方法这次因为没有人会,所以不会使用,等项目完了,我自己去研究一下,很有兴趣。 |
|
返回顶楼 | |
发表时间:2004-06-09
我在项目中的做法是
做个pageCtrl class,封装所有分页操作. 使得对于 WEB层的人员来说,不需要知道分批次取数据的逻辑,就好象一次性取得了所有结果. 定义pageCtrl同时,定义符合分页操作的 Dao Interface. Dao Interface的实例作为PageCtrl的构造参数. Dao和pageCtrl实例的Facade层生成组装. web taglib只负责纯显示职责. 目前使用下来,达到效果. |
|
返回顶楼 | |
发表时间:2004-06-09
那你的分页是直接调用dao
虽然我也觉得最这么调用最直接,也最方便,不过因为已有的系统统一使用facade接口,如果跳过这一接口,直接使用dao,是不是会打乱系统的统一性? |
|
返回顶楼 | |
发表时间:2004-06-09
DAO已经隐含在pageCtrl中了,对于DAO的操作,是由pageCtrl调用的.
我认为在实际使用也是符合分层原则的. facade重要性的是对外提供简单接口, 而不是要求每调用一次数据库操作,都必须->facade->X->dao. 如果WEB层的开发人员,需要知道 上一页,下一页,是怎么样调用Facade层的话,那么才是 facade层的失败. 目前项目中的设计主要由以下几个部分 pageCtrl 知道所有分页操作逻辑 InfPgDao 分页数据取得的操作接口 facade 知道业务逻辑, 哪个查询对应哪个DAO实现,facade 起到的业务逻辑的组织作用. Dao 具体数据库查询逻辑的实现 web 1.新的查询 和 facade交互,取得pagectrl实例. session中保存.<--体现了业务逻辑 2.分页操作, 只需要操做session中的pageCtrl实例.<--显示性操作,与业务逻辑无关. 这样做的目标是, WEB开发人员不需要了解分页的实现细节. 只需要调用 上一页,下一页, 设置当前页 ,取得当前页数据的显示逻辑即可. 其实我最初也是有"破坏分层"的担心, 但随着逐步的实现,觉得这样还是符合分层的. |
|
返回顶楼 | |
发表时间:2004-06-09
tuti 写道 DAO已经隐含在pageCtrl中了,对于DAO的操作,是由pageCtrl调用的.
我认为在实际使用也是符合分层原则的. facade重要性的是对外提供简单接口, 而不是要求每调用一次数据库操作,都必须->facade->X->dao. 如果WEB层的开发人员,需要知道 上一页,下一页,是怎么样调用Facade层的话,那么才是 facade层的失败. 目前项目中的设计主要由以下几个部分 pageCtrl 知道所有分页操作逻辑 InfPgDao 分页数据取得的操作接口 facade 知道业务逻辑, 哪个查询对应哪个DAO实现,facade 起到的业务逻辑的组织作用. Dao 具体数据库查询逻辑的实现 web 1.新的查询 和 facade交互,取得pagectrl实例. session中保存.<--体现了业务逻辑 2.分页操作, 只需要操做session中的pageCtrl实例.<--显示性操作,与业务逻辑无关. 这样做的目标是, WEB开发人员不需要了解分页的实现细节. 只需要调用 上一页,下一页, 设置当前页 ,取得当前页数据的显示逻辑即可. 其实我最初也是有"破坏分层"的担心, 但随着逐步的实现,觉得这样还是符合分层的. 请问三个问题: 1:list算不算业务逻辑?如果算,应该不应该写在bo里面。 2:你所提到的web开发人员只专门的界面开发吗?包括不包括taglib的开发人员? 3:你的方法中是不是tablig调用你封装好的pageCtrl, web的开发人员只需在调用taglib向里面传递参数的时候设置dao的类名就可以了。如果是的话,那我使用facade的话,在taglib中调用facade,web开发人员只需要在调用taglib传递想要翻页的vo名就可以了。 这个和你那个有什么区别?而且,我觉得对web开发人员暴露vo的名字比暴露dao名字好的多。 而且我们这个系统有个问题,权限验证都是在facade做的,都有统一的接口,如果直接使用dao的话,会跳过这一机制。 我刚才和师父讨论了一下,觉得还是采用通过facade调用比较好了。。。 恩,针对你的话,我还向提出一个问题,就是,采用这种facade-》bo-》dao的多层体系,是不是所有的前台调用都要这么一层一层的过来, 比如统计这种调用也这么过来吗? 是不是只和显示有关的调用可以扩过bo这一层,直接和dao打交道,比如list,statistic。 |
|
返回顶楼 | |
发表时间:2004-06-09
to tuti:
我觉得其实没有必要那么复杂。 我的想法是做一个list/iterator的decorator,将查询出来的页面数据包装一下,然后自己写个taglib显示就行了。 |
|
返回顶楼 | |
发表时间:2004-06-09
引用 1:list算不算业务逻辑?如果算,应该不应该写在bo里面
如果这里的list是指 查询或者统计的话,算是业务逻辑,这类操作常常会包含权限控制,应该写在业务逻辑实现层。 引用 2:你所提到的web开发人员只专门的界面开发吗?包括不包括taglib的开发人员?
我们这个项目使用struts,这里的web开发人员是指负责写formbean,action等逻辑的开发人员,也可以算包括taglib的开发人员。 引用 3:你的方法中是不是tablig调用你封装好的pageCtrl
是在action里调用,taglib只是起显示一些状态,如共几页,现在第几页等。 引用 权限验证都是在facade做的,都有统一的接口
即便是查询,也往往是有权限要求的,这也是业务逻辑。在这里我做了一点简化,即 按“查询”按钮的时候,由facade进行权限检查,判断是否返回pageCtrl实例。而在 翻页操作时,认为只是对结果集合的显示操作,而不进行权限判断。翻页操作时,就好象一次取得10000条记录,放在session里,每页只显示10条的逻辑一样。 |
|
返回顶楼 | |
发表时间:2004-06-10
这个分页问题的封装过程,我是这样来理解的。
首先, 可以设想在facade层一个 一次性返回全部数据Collection的业务接口,这个接口包括权限逻辑检查。 其次, 设想对一次性返回的全部数据,在WEB层session里保存,表现上进行分页显示。所有的分页显示逻辑可以用pageCtrl来封装。 最后,表现层的每一页数据,都是分页取得。这样facade层的接口 从返回Collection 变为了返回pageCtrl。这样对于数据是一次性取得,还是分页取得的逻辑就包含在pageCtrl之中了,对外不可见。 而action的调用程序与step2相比要基本不变。也就是说,aciton里的逻辑,不知道分页数据是一次性返回,还是分页取得,只知道,根据输入条件取得返回结果,上一页,下一页,指定页。 至于“taglib向里面传递参数”等封装方式,目标都是在不破坏分层结构的前提下,尽量使调用者使用方便。多传一个参数,都多增加一份耦合度。设计效果要看client端程序是如何来调用封装出的接口。 |
|
返回顶楼 | |
发表时间:2004-06-10
下面是我所想的分页实现,PaginateList是一个附带了分页信息的List。
对于客户端程序员而言,只需要知道service中的findByXXXX接口,tag的调用也很简单,只需要传递返回的List在pageContext中的名字即可,其他的上页,下页,共几页之类的由tag来解决。 我觉得不爽的是,需要额外进行一次查询来觉得记录总数,虽然对于客户端程序员而言是不可见的。 public List findByXXXX(String query, Object[] values, int start, int rows); { // TODO get the count // get the result list List result = ............... //取得分页的数据 return new PaginateList(resultList, start, rows, recordsCount);; } public PagintateList implements List{ private List resultList; private int recordsCount; private int rows; private int start; public PaginateList(List resultList, int start, int rows, int recordsCount);{ this.resultList = resultList; this.start = start; this.rows = rows; this.recordsCount = recordsCount; } ............... } |
|
返回顶楼 | |