设计模式十三之迭代器模式
迭代器模式
“迭代”这个词并不会陌生,我们经常使用Iterator接口对Collection下的集合类进行遍历,常见代码:
1 | Iterator iterator=list.iterator(); |
这便是很好的迭代器模式应用例子。我们可以在不暴露集合类的内部结构情况下,通过迭代器让外部客户端透明的访问其内部的数据。
定义及结构
定义
提供一种可以顺序访问聚合对象中的每个元素的方式,而有不暴露该对象的内部结构。又称为“游标cursor模式”。
模式结构
- 迭代器角色(Iterator):迭代器角色负责定义访问和遍历的接口
- 具体迭代器角色(ConcreteIterator):具体迭代器角色实现迭代器接口,记录当前的游标位置
- 聚合角色(Aggregate): 聚合角色负责提供创建具体迭代器角色的接口
- 具体聚合角色(ConcreteAggregate): 具体聚合角色实现聚合角色接口
结构图
代码
下面通过模仿JavaSDK中的Iterator写一个自己的迭代器。
迭代器角色(Iterator)
1 | /** |
具体聚合角色(ConcreteAggregate)
1 | /** |
客户端
1 | public class Client { |
控制台
1 | aa |
总结
迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。
但是,由于容器与迭代器的关系太密切了,所以大多数语言在实现容器的时候都给提供了迭代器,并且这些语言提供的容器和迭代器在绝大多数情况下就可以满足我们的需要,所以现在需要我们自己去实践迭代器模式的场景还是比较少见的,我们只需要使用语言中已有的容器和迭代器就可以了
优点
- 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
- 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
- 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。
缺点
- 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,感觉像
ArrayList
,我们宁可愿意使用for循环和get方法来遍历集合。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 YD Blog!