定义
提供一种方法访问一个容器(container)对象中的各个元素,而又不暴露该对象的内部细节。
UML
优点
- 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
- 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
- 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。
缺点
- 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合,操作简易度完爆迭代。
应用场景
- 迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。
- 但是,由于容器与迭代器的关系太密切了,所以大多数语言在实现容器的时候都给提供了迭代器,并且这些语言提供的容器和迭代器在绝大多数情况下就可以满足我们的需要,所以现在需要我们自己去实践迭代器模式的场景还是比较少见的,我们只需要使用语言中已有的容器和迭代器就可以了。
示例
考虑这样一个需求,一家大公司合并了一家小公司,而两家公司的工资系统不一样,大公司使用List记录员工工资,小公司使用数组记录员工工资,而这两个不一样的工资系统需要合并进行查询所有人的工资,且需要打印出相同的结果时,我们可以使用迭代器模式来解决这个问题。
Java
1 import java.util.ArrayList; 2 import java.util.List; 3 4 public class Main 5 { 6 public static void main(String[] args) 7 { 8 //访问集团的工资列表 9 PayManager payManager = new PayManager(); 10 //先计算再获取 11 payManager.calcPay(); 12 System.out.println("集团工资列表:"); 13 test(payManager.createIterator()); 14 15 //访问新收购公司的工资列表 16 SalaryManager salaryManager = new SalaryManager(); 17 //先计算再获取 18 salaryManager.calcSalary(); 19 System.out.println("新收购的公司工资列表:"); 20 test(salaryManager.createIterator()); 21 } 22 23 private static void test(Iterator it) 24 { 25 it.first(); 26 while (!it.isDone()) 27 { 28 Object obj = it.currentItem(); 29 System.out.println("the obj==" + obj); 30 it.next(); 31 } 32 } 33 34 /** 35 * 工资模型 36 */ 37 public static class PayModel 38 { 39 /** 40 * 支付工资的人员 41 */ 42 private String userName; 43 44 /** 45 * 支付的工资数额 46 */ 47 private double pay; 48 49 public String getUserName() 50 { 51 return userName; 52 } 53 54 public void setUserName(String userName) 55 { 56 this.userName = userName; 57 } 58 59 public double getPay() 60 { 61 return pay; 62 } 63 64 public void setPay(double pay) 65 { 66 this.pay = pay; 67 } 68 69 public String toString() 70 { 71 return "userName=" + userName + ", pay=" + pay; 72 } 73 } 74 75 /** 76 * 大公司员工工资管理器 77 */ 78 public static class PayManager extends Aggregate 79 { 80 /** 81 * 聚合对象,这里是Java的集合对象 82 */ 83 private List list = new ArrayList(); 84 85 public List getPayList() 86 { 87 return list; 88 } 89 90 public void calcPay() 91 { 92 PayModel pm1 = new PayModel(); 93 pm1.setPay(3800); 94 pm1.setUserName("张三"); 95 96 PayModel pm2 = new PayModel(); 97 pm2.setPay(5800); 98 pm2.setUserName("李四"); 99 100 list.add(pm1); 101 list.add(pm2); 102 } 103 104 public Iterator createIterator() 105 { 106 return new CollectionIteratorImpl(this); 107 } 108 109 public Object get(int index) 110 { 111 Object retObj = null; 112 if (index < this.list.size()) 113 { 114 retObj = this.list.get(index); 115 } 116 return retObj; 117 } 118 119 public int size() 120 { 121 return this.list.size(); 122 } 123 } 124 125 /** 126 * 小公司员工工资管理器 127 */ 128 public static class SalaryManager extends Aggregate 129 { 130 /** 131 * 用数组管理 132 */ 133 private PayModel[] pms = null; 134 135 public PayModel[] getPays() 136 { 137 return pms; 138 } 139 140 public void calcSalary() 141 { 142 //计算工资,并把工资信息填充到工资列表里面 143 //为了测试,做点假数据进去 144 PayModel pm1 = new PayModel(); 145 pm1.setPay(2200); 146 pm1.setUserName("王五"); 147 148 PayModel pm2 = new PayModel(); 149 pm2.setPay(3600); 150 pm2.setUserName("赵六"); 151 152 pms = new PayModel[2]; 153 pms[0] = pm1; 154 pms[1] = pm2; 155 } 156 157 public Iterator createIterator() 158 { 159 return new ArrayIteratorImpl(this); 160 } 161 162 public Object get(int index) 163 { 164 Object retObj = null; 165 if (index < pms.length) 166 { 167 retObj = pms[index]; 168 } 169 return retObj; 170 } 171 172 public int size() 173 { 174 return this.pms.length; 175 } 176 } 177 178 /** 179 * 集合接口 180 */ 181 public static abstract class Aggregate 182 { 183 /** 184 * 工厂方法,创建相应迭代器对象的接口 185 * @return 相应迭代器对象的接口 186 */ 187 public abstract Iterator createIterator(); 188 } 189 190 /** 191 * 迭代器接口 192 */ 193 public interface Iterator 194 { 195 void first(); 196 197 void next(); 198 199 boolean isDone(); 200 201 Object currentItem(); 202 } 203 204 /** 205 * 数组迭代器 206 */ 207 public static class ArrayIteratorImpl implements Iterator 208 { 209 /** 210 * 用来存放被迭代的聚合对象 211 */ 212 private SalaryManager aggregate = null; 213 214 private int index = -1; 215 216 public ArrayIteratorImpl(SalaryManager aggregate) 217 { 218 this.aggregate = aggregate; 219 } 220 221 222 @Override 223 public void first() 224 { 225 index = 0; 226 } 227 228 @Override 229 public void next() 230 { 231 if (index < this.aggregate.size()) 232 { 233 index = index + 1; 234 } 235 } 236 237 @Override 238 public boolean isDone() 239 { 240 if (index == this.aggregate.size()) 241 { 242 return true; 243 } 244 return false; 245 } 246 247 @Override 248 public Object currentItem() 249 { 250 return this.aggregate.get(index); 251 } 252 } 253 254 /** 255 * 集合列表迭代器 256 */ 257 public static class CollectionIteratorImpl implements Iterator 258 { 259 /** 260 * 用来存放被迭代的聚合对象 261 */ 262 private PayManager aggregate = null; 263 264 private int index = -1; 265 266 public CollectionIteratorImpl(PayManager aggregate) 267 { 268 this.aggregate = aggregate; 269 } 270 271 @Override 272 public void first() 273 { 274 index = 0; 275 } 276 277 @Override 278 public void next() 279 { 280 if (index < this.aggregate.size()) 281 { 282 index = index + 1; 283 } 284 } 285 286 @Override 287 public boolean isDone() 288 { 289 if (index == this.aggregate.size()) 290 { 291 return true; 292 } 293 return false; 294 } 295 296 @Override 297 public Object currentItem() 298 { 299 return this.aggregate.get(index); 300 } 301 } 302 }