行为类模式(四):迭代器(Iterator)

定义

提供一种方法访问一个容器(container)对象中的各个元素,而又不暴露该对象的内部细节。

UML

优点

  1. 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
  2. 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
  3. 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。

缺点

  1. 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合,操作简易度完爆迭代。

应用场景

  1. 迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。
  2. 但是,由于容器与迭代器的关系太密切了,所以大多数语言在实现容器的时候都给提供了迭代器,并且这些语言提供的容器和迭代器在绝大多数情况下就可以满足我们的需要,所以现在需要我们自己去实践迭代器模式的场景还是比较少见的,我们只需要使用语言中已有的容器和迭代器就可以了。

示例

考虑这样一个需求,一家大公司合并了一家小公司,而两家公司的工资系统不一样,大公司使用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 }
View Code
原文地址:https://www.cnblogs.com/hammerc/p/4743801.html