欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java模板方法在分页中的使用 java分页模式 

程序员文章站 2024-03-14 16:08:52
...

 

    在日常的编程过程中,经常要处理数据集合。对数据集合处理一般采用下面的接口:

 

    /**
     * 得到集合方法,传入当前页,和每页的大小
     * 
     * @param curPage
     * @param pageSize
     * @return
     */
     public List<T> getList(int curPage, int pageSize)

 

上面的处理过程,即大家通常所说的分页;一般显示的时候,使用上面的方法就可以了,但是,如果要对集合中的全部数据处理呢?一般情况下,会出现下面的代码:

 

	int curPage = 1;
	int pageSize = 100;
	int count = XXXService.getXXXCount();
	int lastPage = count / pageSize + 1;
	while (lastPage >= curPage) {
	    List<XXXType> lists = xxxxService.getXxxxByYyy(curPage,pageSize);
	    if (lists == null) {
	        break;
	    }
	    for (T obj : lists) {
			//对其中的一个进行处理
	    }
	    curPage++;
	}

 

那么,能不能把上面的代码变成一个通用的模式(工具),然后很简单的使用,不用每次都这样的重复呢?

 

让我们分析一下,上面情况下,什么是可变的,什么是不变的?

 

    1、总体的流程是不变的;

    2、得到当前页的list和对其中一个进行处理是可变的

 

分析到这里,可能很多人想到了模板方法类解决这个问题,在spring jdbc中大量使用了这种方法;具体实现时,有2种选择,一个是使用抽象来完成过程1,使用子类来完成过程2,典型如:jdk中InputStream,第二个,使用接口来完成过程2,使用类来完成过程1,如:Thread和Runable;

 

下面采用第二种方式来实现;首先定义接口:

 

public interface ListAction<T> {

    /**
     * 得到集合方法
     * 
     * @param curPage
     * @param pageSize
     * @return
     * @throws Exception
     */
    public List<T> getList(int curPage, int pageSize) throws Exception;

    /**
     * 处理一个对象
     * 
     * @param t
     * @throws Exception
     */
    public void process(T t) throws Exception;

}

 

这个接口中,是分析中可变的部分。再来定义不可变的类:

 

public class OverListUtil<T> {

    private int curPage = 1;

    private int pageSize = 100;

    private int lastPage = 1;

    public void overList(int count, ListAction<T> listAtion) throws Exception {
        lastPage = count / pageSize + 1;
        while (lastPage >= curPage) {
            List<T> lists = listAtion.getList(curPage, pageSize);
            for (T obj : lists) {
                listAtion.process(obj);
            }
            curPage++;
        }
    }

    /**
     * 得到当前处理的页
     * 
     * @return
     */
    public int getCurPage() {
        return curPage;
    }

    public void setCurPage(int curPage) {
        this.curPage = curPage;
    }

    public int getPageSize() {
        return pageSize;
    }

    /**
     * 是否是最后一页
     * 
     * @return
     */
    public boolean isLastPage() {
        return curPage == lastPage;
    }

    /**
     * 设置每页要处理的数量,默认100
     * 
     * @param pageSize
     */
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
}

 

这个类主要对不可变的部分进行抽象,即模板。

 

那么,怎么使用呢?和Thread、Runable的实现一样,下面是个例子:

 

        final int count = 5;

        final OverListUtil<String> olu = new OverListUtil<String>();

        olu.setPageSize(10);

        olu.overList(count, new ListAction<String>() {

            @Override
            public void process(String t) throws Exception {
                // 这里是主要处理逻辑
                System.out.println("正在处理第" + olu.getCurPage() + "页");
                System.out.println("names:" + t);
            }

            @Override
            public List<String> getList(int curPage, int pageSize) throws Exception {
                // 这里一般情况下只需要简单的调用服务即可
                List<String> names = getServiceNames(curPage, pageSize);
                return names;
            }

            // 下面这个模仿一个服务
            private List<String> getServiceNames(int curPage, int pageSize) {
                List<String> names = new ArrayList<String>();
                int lenght = 1;
                if (olu.isLastPage()) {
                    lenght = count - ((olu.getCurPage() - 1) * olu.getPageSize());
                } else {
                    lenght = olu.getPageSize();
                }
                for (int i = 0; i < lenght; i++) {
                    String s = String.valueOf(Math.random() * 100);
                    names.add(s);
                }
                return names;
            }
        });

 

那么为什么不把OverListUtil的overList 定义为static的呢?因为这里使用了泛型,参见泛型

 

 

呵呵,周五了,明天可以好好的玩玩了!祝大家周末愉快!