概念
Iterator Pattern:别名为游标(Cursor),提供一个方法来访问聚合对象,而不用暴露这个对象的内部表示。
使用
- 内部迭代器:内部定义好了迭代规则,完全接手了整个过程,外部只需要调用一次。但是它只能迭代一个数组,要想迭代两个数组必须改变内部函数的实现,违反了开闭原则
1 | // 实现一个each函数,第一个参数是数组,第二个参数是每一步的处理函数 |
- 外部迭代器:必须显式的请求迭代下一个元素,增加了一些调用的复杂度,但相对也增强了迭代器的灵活性,因此我们可以手动地控制整个迭代过程
1 | var Iterator = function (obj) { |
从上面的迭代器实现可以看出,只要被迭代的聚合对象拥有length属性而且可以用下标访问,那么它就是迭代器。Javascript中的类数组对象也是迭代器。
优点
- 支持以不同的方式遍历一个聚合对象,同一个聚合对象可以定义多种遍历方式
- 简化了聚合类:在原有的聚合对象中不需要再自行提供数据遍历等方法
- 增加新的聚合类和迭代器类都很方便,无须修改原有代码,符合开闭原则
缺点
- 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,一定程度上增加了系统的复杂性
- 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展,例如JDK内置迭代器Iterator就无法实现逆向遍历,如果需要实现逆向遍历,只能通过其子类ListIterator等来实现,而ListIterator迭代器无法用于操作Set类型的聚合对象。在自定义迭代器时,创建一个考虑全面的抽象迭代器并不是件很容易的事情