论坛首页 Java企业应用论坛

在多层框架中分页处理的问题(主要是设计方面)

浏览 13903 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-06-10  
tuti 写道
这个分页问题的封装过程,我是这样来理解的。
首先, 可以设想在facade层一个 一次性返回全部数据Collection的业务接口,这个接口包括权限逻辑检查。

其次, 设想对一次性返回的全部数据,在WEB层session里保存,表现上进行分页显示。所有的分页显示逻辑可以用pageCtrl来封装。

最后,表现层的每一页数据,都是分页取得。这样facade层的接口 从返回Collection 变为了返回pageCtrl。这样对于数据是一次性取得,还是分页取得的逻辑就包含在pageCtrl之中了,对外不可见。

而action的调用程序与step2相比要基本不变。也就是说,aciton里的逻辑,不知道分页数据是一次性返回,还是分页取得,只知道,根据输入条件取得返回结果,上一页,下一页,指定页。

至于“taglib向里面传递参数”等封装方式,目标都是在不破坏分层结构的前提下,尽量使调用者使用方便。多传一个参数,都多增加一份耦合度。设计效果要看client端程序是如何来调用封装出的接口。


谢谢你的回答,不过现在我们的讨论已经有点偏离我开始提问的初衷了。

我现在最近还是决定不直接调用dao,还是通过facade-》bo-》dao这么层层提供接口,
获取翻页数据通过调用facade而不是dao。
0 请登录后投票
   发表时间:2004-06-11  
分为三个部分:持久层分页,界面显示(标签库),分页控制.
分页控制是界面显示,持久层分页的连接点.采用AbstractPagerHelper实现:
public abstract class AbstractPagerHelper {
public PageControl newPageControl(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
..................
return pageControl;
}
//每页显示的数据集合,可以在其中调用业务层或持久层方法
public abstract Collection getPagerData(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response,
long start,
long count)
throws Exception;
//总行数,可以在其中调用业务层或持久层方法
public abstract long getRowCount(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception;
}

持久层:
抽象Hibernate的Dialect,实现分页语法的简单封装.

在Action中:
PageControl pageControl = new AbstractPagerHelper() {
...//两个抽象类的实现(从业务层或持久层获取数据),newPageControl会调用这两个方法
}.newPageControl(mapping,form,request,response);
request.setAttribute("pageControl",pageControl);

jsp界面(标签库的样式是模仿bang的:),可以扩展更多的样式):
<smile:pager name="pageControl" page="/personBaseList.do?query=mmm">
<smile:first>First Page</smile:first>
<smile:prev>Pre Page</smile:prev>
<smile:index/>
<smile:next>Next page</smile:next>
<smile:last>Last Page</smile:last>
</smile:pager>
<logic:iterate id="ps" name="pageControl" property="data" type="com.smiletilly.job.person.entity.PersonBaseInfo">
<tr>
<td><bean:write name="ps" property="id"/></td>
<td><bean:write name="ps" property="name"/></td>
</tr>
</logic:iterate>
0 请登录后投票
   发表时间:2004-06-11  
引用
to deeprising


如果不涉及到商业机密的话。
不知你是否可以提供你的tablig代码给我参考一下?^_^
0 请登录后投票
   发表时间:2004-06-11  
为什么不能保持一种简单的设计呢?

假如你要查找系统的所有用户,数据不需要分页,你会怎么做?通常应该是这样:

   List users = userService.findAllUsers();;
   

而你的service可能如下:

    public List findAllUsers(); { 
        List result = ...............           
        return result;
    } 

那么,如果需要分页呢?客户程序员最希望的调用方式是什么?我觉得应该是:
 
    List users = userService.findAllUsers(start, rows);;
 
 
客户程序员就应该是这么写,剩下的事情应该由我们来完成。应该怎么做呢?

我认为Decorator是最直接的方式,给List附件分页的信息,如下:

    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; 
      } 
      ............... 
    } 


这时候UserService只需要这么写就行了:

    public List findAllUsers(int start, int rows); { 
        
        // TODO 取得记录总数
  
        // 取得分页的数据
        List result = ...............  
         
        return new PaginateList(resultList, start, rows, recordsCount);; 
     } 


这样,客户程序员可以和不分页的情况一样处理数据。

那么客户程序员需要在ui上显示Previous, Next, Total records count之类的信息怎么办?提供taglib,类似这样的形式:

    <tagx:paginate list="users"/>

好了,根据属性list的值,你可以取得PaginateList对象users,里面包含了分页所需的信息,该怎么处理不用我说了吧。

我喜欢简单的东西,我喜欢客户程序员只需要写:

    List users = userService.findAllUsers(start, rows);



    <tagx:paginate list="users"/>

这么几句话的感觉。
0 请登录后投票
   发表时间:2004-06-11  
ygxdha 写道
引用
to deeprising


如果不涉及到商业机密的话。
不知你是否可以提供你的tablig代码给我参考一下?^_^


核心代码都贴出来了,tablig是次要的,只是用来显示数据而已,都是围绕PageControl而已~~

射覆请客的思路很新颖,感触很深.他的做法是在业务层构造分页相关数据(PagintateList),我是在表示层构造分页相关数据(PageControl)
 public PagintateList implements List{ 
       private List resultList; //数据
       private int recordsCount; 
       private int rows; 
       private int start;

public class PageControl{
	private long currentPage = 1;
	private long maxPage;
	private long maxRowCount;
	private int rowsPerPage = 20;
	
	private Collection data;//数据
0 请登录后投票
   发表时间:2004-06-11  
List users = userService.findAllUsers(start, rows);;

如果userService算做一个业务接口,start 和 rows 是应该算是显示逻辑,
为什么要暴露在业务接口上。

分页画面不仅是显示,分页本身还有不少需要显示的属性和操作,
光一个List Interface还不太够用。比如共多少页,当前是第几页,
是否有上一页,下一页,共几页,当前页是第XX到YY条等。

对于使用分页浏览的用户来说,一般也都不会关心start和rows,
所以我觉得对于WEB开发人员暴露 start和row参数,显得不自然。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics