职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 1596|回复: 1

java模板方法在分页的使用

[复制链接]
楠楠 发表于 2011-9-4 09:41 | 显示全部楼层 |阅读模式
  
    在日常的编程过程中,经常要处理数据集合。对数据集合处理一般采用下面的接口:

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

    /**
     * 得到集合方法,传入当前页,和每页的大小
     *
     * @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++;   
}  

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

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

        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的呢?因为这里使用了泛型,参见泛型


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

gz-vps 发表于 2011-9-4 09:41 | 显示全部楼层
推荐链接
见证又一个准百万富翁的诞生!
20-30万急聘多名天才Java/MTA软件工程师
3G培训就业月薪平均7K+,不3K就业不花一分钱!


您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-6 04:16 , Processed in 0.136035 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表