由于迭代器模式把聚合对象和访问聚合的机制实现了分离,所以可以在迭代器上实现不同的迭代策略,最为典型的就是实现过滤功能的迭代器。
在实际开发中,对于经常被访问的一些数据可以使用缓存,把这些数据存放在内存中。但是不同的业务功能需要访问的数据是不同的,还有不同的业务访问权限能访问的数据也是不同的,对于这种情况,就可以使用实现过滤功能的迭代器,让不同功能使用不同的迭代器来访问。当然,这种情况也可以结合策略模式来实现。
在实现过滤功能的迭代器中,又有两种常见的需要过滤的情况,一种是对数据进行整条过滤,比如只能查看自己部门的数据;另外一种情况是对数据进行部分过滤,比如某些人不能查看工资数据。
/** * 聚合对象的接口,定义创建相应迭代器对象的接口 */ public abstract class Aggregate { /** * 工厂方法,创建相应迭代器对象的接口 * @return 相应迭代器对象的接口 */ public abstract Iterator createIterator(); } ---------- /** * 客户方已有的工资管理对象 */ public class PayManager extends Aggregate{ private List<PayModel> list = new ArrayList<PayModel>(); /** * 获取工资列表 * @return 工资列表 */ public List<PayModel> getPayList(){ return list; } /** * 计算工资,其实应该有很多参数,为了演示从简 */ public void calcPay(){ //计算工资,并把工资信息填充到工资列表里面 //为了测试,做点假数据进去 PayModel pm1 = new PayModel(); pm1.setPay(3800); pm1.setUserName("张三"); PayModel pm2 = new PayModel(); pm2.setPay(5800); pm2.setUserName("李四"); list.add(pm1); list.add(pm2); } public Iterator createIterator() { return list.iterator(); } } ---------- /** * 被客户方收购的那个公司的工资管理类 */ public class SalaryManager extends Aggregate{ /** * 用数组管理 */ private PayModel[] pms = null; /** * 获取工资列表 * @return 工资列表 */ public PayModel[] getPays(){ return pms; } /** * 计算工资,其实应该有很多参数,为了演示从简 */ public void calcSalary(){ //计算工资,并把工资信息填充到工资列表里面 //为了测试,做点假数据进去 PayModel pm1 = new PayModel(); pm1.setPay(2200); pm1.setUserName("王五"); PayModel pm2 = new PayModel(); pm2.setPay(3600); pm2.setUserName("赵六"); pms = new PayModel[2]; pms[0] = pm1; pms[1] = pm2; } public Iterator createIterator(){ return new ArrayIteratorImpl(this); } public Object get(int index){ Object retObj = null; if(index < pms.length){ retObj = pms[index]; } return retObj; } public int size(){ return this.pms.length; } } ---------- import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * 用来实现访问数组的迭代接口,加入了迭代策略 */ public class ArrayIteratorImpl implements Iterator{ /** * 用来存放被迭代的数组 */ private PayModel[] pms = null; /** * 用来记录当前迭代到的位置索引 */ private int index = 0; public ArrayIteratorImpl(SalaryManager aggregate){ //在这里先对聚合对象的数据进行过滤,比如工资必须在3000以下 Collection<PayModel> tempCol = new ArrayList<PayModel>(); for(PayModel pm : aggregate.getPays()){ if(pm.getPay() < 3000){ tempCol.add(pm); } } //然后把符合要求的数据存放到用来迭代的数组 this.pms = new PayModel[tempCol.size()]; int i=0; for(PayModel pm : tempCol){ this.pms[i] = pm; i++; } } public boolean hasNext() { //判断是否还有下一个元素 if(pms!=null && index<=(pms.length-1)){ return true; } return false; } public Object next() { Object retObj = null; if(hasNext()){ retObj = pms[index]; //每取走一个值,就把已访问索引加1 index++; } //在这里对要返回的数据进行过滤,比如不让查看工资数据 ((PayModel)retObj).setPay(0.0); return retObj; } public void remove() { //暂时可以不实现 } } ---------- public class Client { public static void main(String[] args) { //访问集团的工资列表 PayManager payManager= new PayManager(); //先计算再获取 payManager.calcPay(); System.out.println("集团工资列表:"); test(payManager.createIterator()); //访问新收购公司的工资列表 SalaryManager salaryManager = new SalaryManager(); //先计算再获取 salaryManager.calcSalary(); System.out.println("新收购的公司工资列表:"); test(salaryManager.createIterator()); } /** * 测试通过访问聚合对象的迭代器,是否能正常访问聚合对象 * @param it 聚合对象的迭代器 */ private static void test(Iterator it){ while(it.hasNext()){ PayModel pm = (PayModel)it.next(); System.out.println(pm); } } } 谁定义遍历算法的问题