`
mtnt2008
  • 浏览: 362851 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

阅读更多

 

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

 

    /**
     * 得到集合方法,传入当前页,和每页的大小
     * 
     * @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的呢?因为这里使用了泛型,参见泛型

 

 

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics