迭代器模式(Iterator Pattern): 提供一种方法顺序访问一个聚合对象中的各个元素, 而又不用暴露该对象的内部表示.
设计模式-概述
集合对象一般都有两种职责, 一个是存储数据;二是遍历数据. 迭代器模式就是把第二种职责分离开来, 由迭代器来负责聚合对象内部元素的遍历行为. 它是一种对象行为模式.
结构
它包含了4种角色:
- 抽象迭代器(Iterator): 它定义了访问和遍历元素的接口, 声明了用与遍历元素的方法.
- 具体迭代器(ConcreteIterator): 实现了抽象迭代器, 完成对于聚合对象的遍历.
- 抽象聚合类(Aggregate): 存储和管理元素对象, 声明一个 createIterator()方法用于创建一个迭代器对象.
- 具体聚合类(ConcreteAggregate): 抽象聚合类的子类, 实现了createIterator()方法, 返回一个迭代器实例.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| @@startuml iterator-1 !include common.cuml
Interface(Iterator,"抽象迭代器") { + first() + next() + hasNext() + currentItem() }
Class(ConcreteIterator,"具体迭代器") { + first() + next() + hasNext() + currentItem() }
Class(Aggregate,"抽象聚合类") <<abstract>> { + createIterator() : Iterator }
Class(ConcreteAggregate,"具体聚合类") { + createIterator() : Iterator }
Aggregate <|.. ConcreteAggregate ConcreteAggregate .left.> ConcreteIterator ConcreteAggregate <-right- ConcreteIterator : aggregate Iterator <|.. ConcreteIterator
@@enduml
|
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| package com.yuda.desigmode.main5;
public class Main { public static void main(String[] args) { ConcreteAggregate concreteAggregate = new ConcreteAggregate(); Iterator iterator = concreteAggregate.createIterator(); iterator.first(); iterator.hasNext(); iterator.next(); iterator.currentItem(); } }
interface Iterator { void first();
void next();
boolean hasNext();
Object currentItem(); }
class ConcreteIterator implements Iterator {
private ConcreteAggregate objects;
private int cursor;
public ConcreteIterator(ConcreteAggregate objects) { this.objects = objects; }
@Override public void first() { System.out.println("ConcreteIterator.first"); }
@Override public void next() { System.out.println("ConcreteIterator.next"); }
@Override public boolean hasNext() { System.out.println("ConcreteIterator.hasNext"); return false; }
@Override public Object currentItem() { System.out.println("ConcreteIterator.currentItem"); return objects; } }
abstract class Aggregate { abstract Iterator createIterator(); }
class ConcreteAggregate extends Aggregate {
@Override Iterator createIterator() { return new ConcreteIterator(this); } }
|
使用场景
- 同一个聚合对象如果有多种变量方式, 可以使用迭代器模式, 具体的遍历方式封装到迭代器中, 使用不同迭代器来实现不同的遍历方式, 需要多种遍历方式时使用.
- 聚合对象不需要再考虑维护遍历方式, 仅仅专注于保存数据, 遍历聚合对象无需关注内部实现时使用.
- 遍历元素的客户端使用统一的接口时, 使用迭代器模式能简化遍历方式.
具体应用
- JDK中的集合接口
Collection
, 继承了Iterable
接口, 实现了Collection
的集合类都有实现遍历方法.
- MyBatis中当查询数据库返回大量的数据项时可以使用游标 Cursor, 利用其中的迭代器可以懒加载数据, 避免因为一次性加载所有数据导致内存奔溃, Mybatis 为
Cursor
接口提供了一个默认实现类 DefaultCursor
.