在日常的编程过程中,经常要处理数据集合。对数据集合处理一般采用下面的接口:
/**
* 得到集合方法,传入当前页,和每页的大小
*
* @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的呢?因为这里使用了泛型,参见泛型
呵呵,周五了,明天可以好好的玩玩了!祝大家周末愉快!
|